summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/unit/flash_test.ts29
-rw-r--r--ext/flash/lib.rs56
2 files changed, 70 insertions, 15 deletions
diff --git a/cli/tests/unit/flash_test.ts b/cli/tests/unit/flash_test.ts
index 087e5d0f2..a2011a076 100644
--- a/cli/tests/unit/flash_test.ts
+++ b/cli/tests/unit/flash_test.ts
@@ -2205,6 +2205,35 @@ Deno.test(
},
);
+// https://github.com/denoland/deno/issues/15549
+Deno.test(
+ { permissions: { net: true } },
+ async function testIssue15549() {
+ const ac = new AbortController();
+ const promise = deferred();
+ let count = 0;
+ const server = Deno.serve(() => {
+ count++;
+ return new Response(`hello world ${count}`);
+ }, {
+ async onListen() {
+ const res1 = await fetch("http://localhost:9000/");
+ assertEquals(await res1.text(), "hello world 1");
+
+ const res2 = await fetch("http://localhost:9000/");
+ assertEquals(await res2.text(), "hello world 2");
+
+ promise.resolve();
+ ac.abort();
+ },
+ signal: ac.signal,
+ });
+
+ await promise;
+ await server;
+ },
+);
+
function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
const tp = new TextProtoReader(r);
diff --git a/ext/flash/lib.rs b/ext/flash/lib.rs
index 65d52d083..0714e379d 100644
--- a/ext/flash/lib.rs
+++ b/ext/flash/lib.rs
@@ -987,22 +987,48 @@ fn run_server(
// sockets.remove(&token);
continue 'events;
}
- Ok(read) => match req.parse(&buffer[..offset + read]) {
- Ok(httparse::Status::Complete(n)) => {
- body_offset = n;
- body_len = offset + read;
- socket.parse_done = ParseStatus::None;
- break;
- }
- Ok(httparse::Status::Partial) => {
- socket.parse_done = ParseStatus::Ongoing(offset + read);
- continue;
- }
- Err(_) => {
- let _ = socket.write(b"HTTP/1.1 400 Bad Request\r\n\r\n");
- continue 'events;
+ Ok(read) => {
+ match req.parse(&buffer[..offset + read]) {
+ Ok(httparse::Status::Complete(n)) => {
+ body_offset = n;
+ body_len = offset + read;
+ socket.parse_done = ParseStatus::None;
+ // On Windows, We must keep calling socket.read() until it fails with WouldBlock.
+ //
+ // Mio tries to emulate edge triggered events on Windows.
+ // AFAICT it only rearms the event on WouldBlock, but it doesn't when a partial read happens.
+ // https://github.com/denoland/deno/issues/15549
+ #[cfg(target_os = "windows")]
+ match &mut socket.inner {
+ InnerStream::Tcp(ref mut socket) => {
+ poll
+ .registry()
+ .reregister(socket, token, Interest::READABLE)
+ .unwrap();
+ }
+ InnerStream::Tls(ref mut socket) => {
+ poll
+ .registry()
+ .reregister(
+ &mut socket.sock,
+ token,
+ Interest::READABLE,
+ )
+ .unwrap();
+ }
+ };
+ break;
+ }
+ Ok(httparse::Status::Partial) => {
+ socket.parse_done = ParseStatus::Ongoing(offset + read);
+ continue;
+ }
+ Err(_) => {
+ let _ = socket.write(b"HTTP/1.1 400 Bad Request\r\n\r\n");
+ continue 'events;
+ }
}
- },
+ }
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
break 'events
}