Skip to content

Commit

Permalink
fix(js-runtime): set content-length header for POST/PUT with null body (
Browse files Browse the repository at this point in the history
  • Loading branch information
QuiiBz committed Jun 5, 2023
1 parent 0174cad commit 28bd4c6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .changeset/breezy-cycles-glow.md
@@ -0,0 +1,7 @@
---
'@lagon/js-runtime': patch
'@lagon/cli': patch
'@lagon/serverless': patch
---

Set content-length header to 0 when body is null and method POST or PUT in `fetch()`
42 changes: 42 additions & 0 deletions crates/runtime/tests/fetch.rs
Expand Up @@ -607,3 +607,45 @@ async fn fetch_https() {
)
.await;
}

#[tokio::test]
async fn fetch_set_content_length() {
utils::setup();
let server = Server::run();
server.expect(
Expectation::matching(all_of![
any_of![
request::method_path("POST", "/"),
request::method_path("PUT", "/")
],
request::headers(contains(("content-length", "0")))
])
.times(2)
.respond_with(status_code(200)),
);
let url = server.url("/");

let (send, receiver) = utils::create_isolate(IsolateOptions::new(format!(
"export async function handler() {{
await fetch('{url}', {{
method: 'POST',
}});
await fetch('{url}', {{
method: 'PUT',
}});
return new Response('Ok');
}}"
)));
send(Request::default());

utils::assert_response(
&receiver,
Response::builder()
.header(CONTENT_TYPE, "text/plain;charset=UTF-8")
.body("Ok".into())
.unwrap(),
)
.await;
}
10 changes: 10 additions & 0 deletions packages/js-runtime/src/runtime/http/fetch.ts
@@ -1,6 +1,8 @@
(globalThis => {
const isHeadersObject = (headers?: HeadersInit): headers is Headers => !!headers && 'entries' in headers;

const FORCE_0_CONTENT_LENGTH_METHODS = ['POST', 'PUT'];

globalThis.fetch = async (input, init) => {
let headers: Map<string, string> | undefined = undefined;

Expand Down Expand Up @@ -29,6 +31,14 @@
}
}

if (body === undefined && init?.method && FORCE_0_CONTENT_LENGTH_METHODS.includes(init.method)) {
if (!headers) {
headers = new Map();
}

headers?.set('content-length', '0');
}

const checkAborted = () => {
if (init?.signal?.aborted) {
throw new Error('Aborted');
Expand Down

0 comments on commit 28bd4c6

Please sign in to comment.