Skip to content

Commit

Permalink
[python] Fixed python.net.SslSocket when python-version >= 3.4 (HaxeF…
Browse files Browse the repository at this point in the history
…oundation#8401)

The issue where SslSocket throws an exception is due to hostName being
null in wrap_socket.  This fix delays wrap_socket until after connect is
called, so we can pass a host in.
  • Loading branch information
theJenix committed Mar 28, 2023
1 parent b24ae68 commit 1e41e5c
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 6 deletions.
5 changes: 5 additions & 0 deletions std/python/_std/sys/net/Socket.hx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ private class SocketOutput extends haxe.io.Output {
__s = new PSocket();
}

function __rebuildIoStreams():Void {
input = new SocketInput(__s);
output = new SocketOutput(__s);
}

public function close():Void {
__s.close();
}
Expand Down
39 changes: 34 additions & 5 deletions std/python/net/SslSocket.hx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ package python.net;
import python.lib.Ssl;
import python.lib.ssl.Purpose;
import python.lib.socket.Socket as PSocket;
import python.lib.Socket in PSocketModule;
import sys.net.Host;

class SslSocket extends sys.net.Socket {
var hostName:String;
var _timeout:Null<Float> = null;
var _blocking:Null<Bool> = null;
var _fastSend:Null<Bool> = null;

override function __initSocket():Void {
function wrapSocketWithSslContext(hostName:String):Void {
#if (python_version >= 3.4)
var context = Ssl.create_default_context(Purpose.SERVER_AUTH);
#else
Expand All @@ -43,16 +46,42 @@ class SslSocket extends sys.net.Socket {
context.options |= Ssl.OP_NO_COMPRESSION;
#end
context.options |= Ssl.OP_NO_TLSv1 #if (python_version >= 3.4) | Ssl.OP_NO_TLSv1_1 #end; // python 3.4 | Ssl.OP_NO_TLSv1_1;
__s = new PSocket();
__s = context.wrap_socket(__s, false, true, true, this.hostName);
__s = context.wrap_socket(__s, false, true, true, hostName);
if (_timeout != null) {
super.setTimeout(_timeout);
}

if (_blocking != null) {
super.setBlocking(_blocking);
}

if (_fastSend != null) {
super.setFastSend(_fastSend);
}
__rebuildIoStreams();
}

public override function connect(host:Host, port:Int):Void {
this.hostName = host.host;
wrapSocketWithSslContext(host.host);
super.connect(host, port);
}

public override function bind(host:Host, port:Int):Void {
throw new haxe.exceptions.NotImplementedException();
}

public override function setTimeout(timeout:Float):Void {
_timeout = timeout;
super.setTimeout(_timeout);
}

public override function setBlocking(b:Bool):Void {
_blocking = b;
super.setBlocking(_blocking);
}

public override function setFastSend(b:Bool):Void {
_fastSend = b;
super.setFastSend(_fastSend);
}
}
2 changes: 2 additions & 0 deletions tests/runci/targets/Python.hx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class Python {
runCommand("haxe", ["compile-python.hxml"].concat(args));
for (py in pys) {
runCommand(py, ["bin/unit.py"]);
// Additional test for python-version >= 3.4
runCommand(py, ["bin/unit34.py"]);
}

changeDirectory(sysDir);
Expand Down
11 changes: 10 additions & 1 deletion tests/unit/compile-python.hxml
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
compile-each.hxml

--each

--main unit.TestMain
-python bin/unit.py
-python bin/unit.py

--next

-D python-version=3.4
--main unit.TestMain
-python bin/unit34.py
55 changes: 55 additions & 0 deletions tests/unit/src/unit/issues/Issue8401.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package unit.issues;

import sys.net.Host;

class Issue8401 extends unit.Test {
function testNew() {
var sock = new python.net.SslSocket();
// With Issue8401, construction fails immediately; if we get this far, it's a pass
utest.Assert.pass();
}

@:access(python.net.SslSocket.__s)
@:access(python.net.SslSocket.wrapSocketWithSslContext)
function testTimeout() {
var sock = new python.net.SslSocket();
// gettimeout is not currently defined in the python socket extern, but it's
// present in the python socket type.
eq(null, (cast sock.__s).gettimeout());
sock.setTimeout(500);
eq(500, (cast sock.__s).gettimeout());
// This will change __s. Make sure we set the timeout properly.
sock.wrapSocketWithSslContext("127.0.0.1");
eq(500, (cast sock.__s).gettimeout());
}

#if (python_verion >= 3.7)
@:access(python.net.SslSocket.__s)
@:access(python.net.SslSocket.wrapSocketWithSslContext)
function testBlocking() {
var sock = new python.net.SslSocket();
// getblocking is not currently defined in the python socket extern, but it's
// present in the python socket type.
t((cast sock.__s).getblocking());
sock.setBlocking(false);
f((cast sock.__s).getblocking());
// This will change __s. Make sure we set the timeout properly.
sock.wrapSocketWithSslContext("127.0.0.1");
f((cast sock.__s).getblocking());
}
#end

@:access(python.net.SslSocket.__s)
@:access(python.net.SslSocket.wrapSocketWithSslContext)
function testFastSend() {
var sock = new python.net.SslSocket();
// getsockopt is not currently defined in the python socket extern, but it's
// present in the python socket type.
eq(0, (cast sock.__s).getsockopt(python.lib.Socket.SOL_TCP, python.lib.Socket.TCP_NODELAY));
sock.setFastSend(true);
eq(1, (cast sock.__s).getsockopt(python.lib.Socket.SOL_TCP, python.lib.Socket.TCP_NODELAY));
// This will change __s. Make sure we set the timeout properly.
sock.wrapSocketWithSslContext("127.0.0.1");
eq(1, (cast sock.__s).getsockopt(python.lib.Socket.SOL_TCP, python.lib.Socket.TCP_NODELAY));
}
}

0 comments on commit 1e41e5c

Please sign in to comment.