mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(ext/flash): reregister socket on partial read on Windows (#16076)
This commit is contained in:
parent
fcb20ab952
commit
e2828ad762
2 changed files with 70 additions and 15 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue