3

I'm trying to make a HTTP server using haxe (4) with HashLink (1.9.0) and sockets doesn't seems to work very well.

import haxe.io.Error;
import sys.net.Host;
import sys.net.Socket;

class Main {
    static public function main() {

        var _aSocketDistant = new List<Socket>();

        var _oSocketMaster = new Socket();
        _oSocketMaster.bind( new Host( 'localhost' ), 8000);
        _oSocketMaster.setBlocking( false );
        _oSocketMaster.listen( 9999 );

        while(true) {

            // Accepting socket
            var oSocketDistant = _oSocketMaster.accept();
            if ( oSocketDistant != null ) {
                trace( 'opening : ' + oSocketDistant.peer() );
                oSocketDistant.setBlocking( false );
                _aSocketDistant.add( oSocketDistant );
            }

            // Trying to read from each socket 
            for ( oSocketDistant in _aSocketDistant ) {
                try {
                    trace( oSocketDistant.read() );
                } catch ( e :Dynamic ) {
                    if ( e != Error.Blocked )
                        throw e;
                }
            }

        }
    }
}

Running this bit of code and then calling http://localhost:8000/ using firefox gets me the following :

Main.hx:27: opening : {host : 127.0.0.1, port : 65154}

The distant socket never have any message to be read. Shouldn't it send the request?

Gama11
  • 31,714
  • 9
  • 78
  • 100
Jeremy Giner
  • 105
  • 4
  • I only know that hashlink has `libuv`, So I think it might be better than `sys.net.Socket`. – r32 Apr 07 '19 at 03:10

1 Answers1

2

The problem seems to be the use of read(). It seems this is not meant to be used on non-blocking sockets:

Your actual issue is that read() will read the whole data. On a blocking socket that would block until the connection is closed. On a non blocking socket that will always raise Blocking. You instead have to use input.readBytes which will return the number of bytes read, and then make sure you correctly manage your buffer data.

In this case, using input.readLine() is probably the easiest solution:

trace(oSocketDistant.input.readLine());

With that, I can see the HTTP request as expected:

Main.hx:20: opening : {host : 127.0.0.1, port : 50231}
Main.hx:29: GET / HTTP/1.1
Main.hx:29: Host: localhost:8008
Main.hx:29: Connection: keep-alive
Main.hx:29: Upgrade-Insecure-Requests: 1
Main.hx:29: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Main.hx:29: DNT: 1
Main.hx:29: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Main.hx:29: Accept-Encoding: gzip, deflate, br
Main.hx:29: Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Main.hx:29: Cookie: Idea-369662de=0cbb3289-7f2c-4f82-a094-7409dba8cfb0
Main.hx:29:
Gama11
  • 31,714
  • 9
  • 78
  • 100
  • Ok, i think i understand now, the read does not work probably because it require the end of the stream (which never comes) but on the other hand functions like readByte or readLine will result since they only require a character or a size to end their reading. – Jeremy Giner Apr 06 '19 at 19:41