rakudo / rakudo

🦋 Rakudo – Raku on MoarVM, JVM, and JS
https://rakudo.org/
Artistic License 2.0
1.71k stars 373 forks source link

Some bug with a combination of $*KERNEL.hardware, slurp, run and Cro #1595

Open AlexDaniel opened 6 years ago

AlexDaniel commented 6 years ago

OK here's the golf:

#!/usr/bin/env perl6
use Cro::HTTP::Router;
use Cro::HTTP::Server;

my $host-arch = $*KERNEL.hardware; # NEEDED!

my $application = route {
    get {
        say ‘enter’;
        $ = run ‘true’; # NEEDED!
        say ‘after’;
        content 'text/plain', "Hello!";
    }
}

slurp; # slurps whatever we have on stdin, NEEDED!
my Cro::Service $share = Cro::HTTP::Server.new: :$application,
    :host(‘0.0.0.0’), :port(10001);
$share.start; # kinda NEEDED can't do it without it

sleep ∞

Run it like this:

perl6 frustratable.p6 <<< 'blah stdin'

Now go to http://localhost:10001/, the page will open just fine. You'll see “Hello!” and in the terminal you'll see this:

enter
after

Refresh the page (EDIT: press Ctrl+F5 instead of just F5), and you'll not get a response again (you'll be waiting until it times out). No output in the terminal, nothing.

AlexDaniel commented 6 years ago

\<timotimo> i get loads and loads of enters and afters \<timotimo> i.e. it keeps working

:(

AlexDaniel commented 6 years ago

FWIW Please contact me if ssh access to the machine where this happens is needed. (I can reproduce on whateverable server and on my laptop, both using Cro 0.7.3 and HEAD-ish rakudo)

zoffixznet commented 6 years ago

What browser are you using?

I can't repro under normal use on 2018.01—refreshing all I want and it works.

However, if I load a page in Firefox and then try to load it in Chrome, it "hangs". Also hangs if I try to do it vice-versa (load in Chrome and then in FF).

Also hangs on second connection if I telnet to it:

$ telnet localhost 10001
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 200 OK
Content-type: text/plain; charset=utf-8
Content-length: 6

Hello!Connection closed by foreign host.
$ telnet localhost 10001
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.0

*no response*

Also hangs on second use with WWW:

$ perl6 -MWWW -e 'say get "http://localhost:10001"'
Hello!
$ perl6 -MWWW -e 'say get "http://localhost:10001"'

*no response*

So sounds like Cro is not happy if it's not getting something it got during previous request. Here's a LiveHTTPHeaders capture of the request from Firefox from refreshing the page (where it works without hangs).

If I replay this via telnet, I get no hang, so just need to golf this to figure out which piece makes it not hang:

http://localhost:10001/

GET / HTTP/1.1
Host: localhost:10001
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 6
----------------------------------------------------------
http://localhost:10001/

GET / HTTP/1.1
Host: localhost:10001
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 6
----------------------------------------------------------
http://localhost:10001/

GET / HTTP/1.1
Host: localhost:10001
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 6
zoffixznet commented 6 years ago

If I replay this via telnet, I get no hang, so just need to golf this

Well, one golf I got it simply the HTTP version; but do browsers even try HTTP/1.0 that it'd get a hang? Probably not the main reason.

No hang with

GET / HTTP/1.1
Host: localhost

Hang:

GET / HTTP/1.0

(Host is mandatory in HTTP/1.1, but isn't in HTTP/1.0, but even if I include it in HTTP/1.0, I get a hang)

zoffixznet commented 6 years ago

but do browsers even try HTTP/1.0

Nope, here's a WireShark dump of a packet that never gets a response to:

GET / HTTP/1.1
Host: localhost:10001
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/28.0.1500.52 Chrome/28.0.1500.52 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
AlexDaniel commented 6 years ago

Oh! I know what I'm doing differently! I'm hitting Ctrl+F5 instead of just F5! That's using firefox.

jnthn commented 6 years ago

Curious that it requires the run too. I wonder if we can golf Cro out of it completely, by replacing that with some structurally similar hack HTTP server using IO::Socket::Async.

jnthn commented 6 years ago

That said, that headers have an impact makes me wonder if it could somehow be a Cro thing, but then the run and, more so, the need to call $*KERNEL.hardware, play into this also, when they really shouldn't make any difference if it's a pure Cro bug.

AlexDaniel commented 6 years ago

This is still an issue, ~and the workaround is no longer working :(~

(still reproducible with the snippet in the OP)

AlexDaniel commented 6 years ago

~Ah, hm. There are probably two issues. The workaround is working again with MVM_JIT_DISABLE=1.~ (oops it's more like something about precomp)