-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TLS not properly flushed, causing "large" responses to arrive incompletely #10049
Comments
Possibly related: #9692 |
Yep, sounds like it's the same issue or at least very much related. However, I experienced problems with the latest version of deno (1.8.3) on CentOS 8, didn't test on Windows or in WSL. |
I think the problem lies with deno_std's HTTP server implementation and not with our implementation of TLS. const listener = Deno.listenTls({
hostname: "localhost",
port: 8443,
certFile: "./cert.pem",
keyFile: "./key.pem",
});
const EOL = "\r\n";
let n = 0;
for await (const conn of listener) {
const char = "a".charCodeAt(0) + (n++ % 26);
const buf = new Uint8Array(2 ** 17);
buf.fill(char);
let head = new TextEncoder().encode(
[`HTTP/1.1 200 OK`, `Content-Length: ${buf.length}`].join(EOL) + EOL + EOL
);
await conn.write(head);
await conn.write(buf);
} |
This seems likely to me because the problem didn't happen in deno version 1.7 and previous versions. |
@piscisaureus running that mock server on CentOS 8, deno 1.8.3, and trying to fetch the content with curl, the request hangs at 75% after receiving 98304 bytes. My browser is able to fetch the whole thing. Edit: I just noticed that when I hit F5 two times in quick succession, the request hangs in the browser as well. It feels like this happens when I refresh before the page finishes loading, but this may be optical deception.
|
…ite half" using tokio::io::split() to allow concurrent Conn#read() and Conn#write() calls without one blocking the other. However, this introduced a bug: outgoing data gets discarded when the TLS stream is gracefully closed, because the read half is closed too early, before all TLS control data has been received. Fixes: denoland#9692 Fixes: denoland#10049 Fixes: denoland#10296 Fixes: denoland/std#750
denoland#10146) In denoland#9118, TLS streams were split into a "read half" and a "write half" using tokio::io::split() to allow concurrent Conn#read() and Conn#write() calls without one blocking the other. However, this introduced a bug: outgoing data gets discarded when the TLS stream is gracefully closed, because the read half is closed too early, before all TLS control data has been received. Fixes: denoland#9692 Fixes: denoland#10049 Fixes: denoland#10296 Fixes: denoland/std#750
|
I have no idea what just happened: the merge, then revert, reopening this issue but actually no? Has the issue been fixed in the end? :) |
I've run into an issue with
serveTLS
where serving "large" files (Nuxt javascript files in this case) fails. The request completes on the server side, or so it seems, but the socket does not close and thus the client (browser or cURL) does not stop loading.POC:
My browser (chrome) stops after exactly receiving 64kiB, or finishes if the file is smaller than that. Trying to get the same files with cURL only gives me 32kiB.
Possible cause
@Juerd, @supakeen and I figured out it might have something to do with the fact that in
writeResponse
on line 289,writer.flush()
is called, which writes the contents of its buffer to the underlying writer, but does not flush this underlying layer in case it has a buffer of itself, which is the case with TLS.Is it possible someone missed this particular comment in Tokio TLS, the library Deno uses for its TLS implementation? (kudo's to @Juerd for finding that)
The text was updated successfully, but these errors were encountered: