mirror of
https://github.com/denoland/deno.git
synced 2025-10-03 15:44:36 +00: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 {
|
function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
|
||||||
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
|
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
|
||||||
const tp = new TextProtoReader(r);
|
const tp = new TextProtoReader(r);
|
||||||
|
|
|
@ -987,22 +987,48 @@ fn run_server(
|
||||||
// sockets.remove(&token);
|
// sockets.remove(&token);
|
||||||
continue 'events;
|
continue 'events;
|
||||||
}
|
}
|
||||||
Ok(read) => match req.parse(&buffer[..offset + read]) {
|
Ok(read) => {
|
||||||
Ok(httparse::Status::Complete(n)) => {
|
match req.parse(&buffer[..offset + read]) {
|
||||||
body_offset = n;
|
Ok(httparse::Status::Complete(n)) => {
|
||||||
body_len = offset + read;
|
body_offset = n;
|
||||||
socket.parse_done = ParseStatus::None;
|
body_len = offset + read;
|
||||||
break;
|
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 => {
|
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
|
||||||
break 'events
|
break 'events
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue