1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

fix(ext/flash): reregister socket on partial read on Windows (#16076)

This commit is contained in:
Divy Srivastava 2022-09-28 11:52:24 -07:00 committed by GitHub
parent fcb20ab952
commit e2828ad762
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 15 deletions

View file

@ -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);

View file

@ -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(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;
}
}
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
}