sergot / http-useragent

Web user agent class for Perl 6.
MIT License
36 stars 39 forks source link

Crash on closed socket in the middle of request. #179

Closed wictory closed 7 years ago

wictory commented 7 years ago

Hi!

When I'm connecting to a server which times out, and closes the connection, in the middle of the request, the whole MoarVM crashes for me instead of giving me an exception.

How to reproduce: Start up server.p6 and run client.p6 from this gist, one can after this see that moarstarts using 100% CPU, and nothning more happens.

jonathanstowe commented 7 years ago

I think you are going to have to be more specific about what actual error you are getting as here with a fairly recent version of HTTP::UserAgent I get the expected exception from the request:

[jonathan@coriolanus junk]$ perl6 client
==>>Send
GET / HTTP/1.1
Host: localhost:3333

Internal Error: 'server returned no data'
  in method get-response at /home/jonathan/.rakudobrew/moar-nom/install/share/perl6/site/sources/08AE7EE25C62E75E3F2D2BF6BA0F001DEB9A1001 (HTTP::UserAgent) line 270
  in method request at /home/jonathan/.rakudobrew/moar-nom/install/share/perl6/site/sources/08AE7EE25C62E75E3F2D2BF6BA0F001DEB9A1001 (HTTP::UserAgent) line 136
  in method get at /home/jonathan/.rakudobrew/moar-nom/install/share/perl6/site/sources/08AE7EE25C62E75E3F2D2BF6BA0F001DEB9A1001 (HTTP::UserAgent) line 102
  in method get at /home/jonathan/.rakudobrew/moar-nom/install/share/perl6/site/sources/08AE7EE25C62E75E3F2D2BF6BA0F001DEB9A1001 (HTTP::UserAgent) line 105
  in block <unit> at client line 5

The rakudo version from perl6 -v would be useful too.

wictory commented 7 years ago

Hi!

$ perl6 -v                                                 
This is Rakudo version 2017.07-137-g46ef1b5b4 built on MoarVM version 2017.07-318-g604da4d0             
implementing Perl 6.c.
$ uname -srvm
Linux 4.11.11-300.fc26.x86_64 #1 SMP Mon Jul 17 16:32:11 UTC 2017 x86_64

When I have

my Blob:D $response = Q[HTTP/1.1 200 OK
Access-Control-Allow-Origin: * 
Cache-Control: no-cache 
Content-Type: application/json 
Connection: keep-alive 
Transfer-Encoding: chunked 
].encode;

, I get the same error as you. It seems that when I copy-paste the code from the gist, the extra newline gets lost, do you have the same situation?

jonathanstowe commented 7 years ago

Ah I see now. Yes it appears to trying to get the body and not getting the close signal. I'll have a better look.

jonathanstowe commented 7 years ago

Ha, found it! In the code that gets the chunked body there is a clause which attempts to get a single byte which has a comment:

           # XXX Reading 1 byte is inefficient code.
            #
            # But IO::Socket#read/IO::Socket#recv reads from socket until
            # fill the requested size.
            #
            # It cause hang-up on socket reading.

Except it doesn't check whether it got a byte or not, so it carries on attempting to get the incomplete chunk forever. I think it should probably throw an exception in this case, but in the first place I'll commit a fix that doesn't as I think the chunked case is the only place this can arise.