This commit is contained in:
Dante
2026-05-21 23:40:20 -07:00
parent 3e2915dff7
commit 877a69d844
5737 changed files with 29796 additions and 1589684 deletions

View File

@ -33,6 +33,8 @@ class Http extends haxe.http.HttpBase {
public var cnxTimeout:Float;
public var responseHeaders:Map<String, String>;
private var responseHeadersSameKey:Map<String, Array<String>>;
var chunk_size:Null<Int>;
var chunk_buf:haxe.io.Bytes;
var file:{
@ -104,7 +106,7 @@ class Http extends haxe.http.HttpBase {
sock = new java.net.SslSocket();
#elseif python
sock = new python.net.SslSocket();
#elseif (!no_ssl && (hxssl || hl || cpp || (neko && !(macro || interp) || eval)))
#elseif (!no_ssl && (hxssl || hl || cpp || (neko && !(macro || interp) || eval) || (lua && !lua_vanilla)))
sock = new sys.ssl.Socket();
#elseif (neko || cpp)
throw "Https is only supported with -lib hxssl";
@ -252,6 +254,23 @@ class Http extends haxe.http.HttpBase {
}
}
/**
Returns an array of values for a single response header or returns
null if no such header exists.
This method can be useful when you need to get a multiple headers with
the same name (e.g. `Set-Cookie`), that are unreachable via the
`responseHeaders` variable.
**/
public function getResponseHeaderValues(key:String):Null<Array<String>> {
var array = responseHeadersSameKey.get(key);
if (array == null) {
var singleValue = responseHeaders.get(key);
return (singleValue == null) ? null : [ singleValue ];
} else {
return array;
}
}
function writeBody(body:Null<BytesOutput>, fileInput:Null<Input>, fileSize:Int, boundary:Null<String>, sock:Socket) {
if (body != null) {
var bytes = body.getBytes();
@ -284,9 +303,13 @@ class Http extends haxe.http.HttpBase {
var s = haxe.io.Bytes.alloc(4);
sock.setTimeout(cnxTimeout);
while (true) {
var p = sock.input.readBytes(s, 0, k);
while (p != k)
p += sock.input.readBytes(s, p, k - p);
var p = 0;
while (p != k) {
try {
p += sock.input.readBytes(s, p, k - p);
}
catch (e:haxe.io.Eof) { }
}
b.addBytes(s, 0, k);
switch (k) {
case 1:
@ -362,6 +385,22 @@ class Http extends haxe.http.HttpBase {
var hname = a.shift();
var hval = if (a.length == 1) a[0] else a.join(": ");
hval = StringTools.ltrim(StringTools.rtrim(hval));
{
var previousValue = responseHeaders.get(hname);
if (previousValue != null) {
if (responseHeadersSameKey == null) {
responseHeadersSameKey = new haxe.ds.Map<String, Array<String>>();
}
var array = responseHeadersSameKey.get(hname);
if (array == null) {
array = new Array<String>();
array.push(previousValue);
responseHeadersSameKey.set(hname, array);
}
array.push(hval);
}
}
responseHeaders.set(hname, hval);
switch (hname.toLowerCase()) {
case "content-length":

View File

@ -0,0 +1,58 @@
package sys.thread;
#if (!target.threaded)
#error "This class is not available on this target"
#end
/**
Creates a new condition variable.
Conditions variables can be used to block one or more threads at the same time,
until another thread modifies a shared variable (the condition)
and signals the condition variable.
**/
@:coreApi extern class Condition {
/**
Create a new condition variable.
A thread that waits on a newly created condition variable will block.
**/
function new():Void;
/**
Acquires the internal mutex.
**/
function acquire():Void;
/**
Tries to acquire the internal mutex.
@see `Mutex.tryAcquire`
**/
function tryAcquire():Bool;
/***
Releases the internal mutex.
**/
function release():Void;
/**
Atomically releases the mutex and blocks until the condition variable pointed is signaled by a call to
`signal` or to `broadcast`. When the calling thread becomes unblocked it
acquires the internal mutex.
The internal mutex should be locked before this function is called.
**/
function wait():Void;
/**
Unblocks one of the threads that are blocked on the
condition variable at the time of the call. If no threads are blocked
on the condition variable at the time of the call, the function does nothing.
**/
function signal():Void;
/**
Unblocks all of the threads that are blocked on the
condition variable at the time of the call. If no threads are blocked
on the condition variable at the time of the call, the function does
nothing.
**/
function broadcast():Void;
}

View File

@ -28,8 +28,13 @@ class EventLoop {
final waitLock = new Lock();
var promisedEventsCount = 0;
var regularEvents:Null<RegularEvent>;
var isMainThread:Bool;
static var CREATED : Bool;
public function new():Void {}
public function new():Void {
isMainThread = !CREATED;
CREATED = true;
}
/**
Schedule event for execution every `intervalMs` milliseconds in current loop.
@ -93,13 +98,14 @@ class EventLoop {
case null:
case e: e.next = event.next;
}
event.next = event.previous = null;
mutex.release();
}
/**
Notify this loop about an upcoming event.
This makes the thread to stay alive and wait for as many events as many times
`.promise()` was called. These events should be added via `.runPromised()`
This makes the thread stay alive and wait for as many events as the number of
times `.promise()` was called. These events should be added via `.runPromised()`.
**/
public function promise():Void {
mutex.acquire();
@ -164,8 +170,8 @@ class EventLoop {
/**
Execute all pending events.
Wait and execute as many events as many times `promiseEvent()` was called.
Runs until all repeating events are cancelled and no more events is expected.
Wait and execute as many events as the number of times `promise()` was called.
Runs until all repeating events are cancelled and no more events are expected.
Depending on a target platform this method may be non-reentrant. It must
not be called from event callbacks.
@ -221,7 +227,7 @@ class EventLoop {
// Run regular events
for(i in 0...eventsToRunIdx) {
if(!regularsToRun[i].cancelled)
if(!regularsToRun[i].cancelled)
regularsToRun[i].run();
regularsToRun[i] = null;
}
@ -249,6 +255,16 @@ class EventLoop {
oneTimersToRun[i] = null;
}
// run main events
if( isMainThread ) {
var next = @:privateAccess haxe.MainLoop.tick();
if( haxe.MainLoop.hasEvents() ) {
eventsToRunIdx++;
if( nextEventAt > next )
nextEventAt = next;
}
}
// Some events were executed. They could add new events to run.
if(eventsToRunIdx > 0) {
nextEventAt = -2;
@ -272,4 +288,4 @@ private class RegularEvent {
this.nextRunTime = nextRunTime;
this.interval = interval;
}
}
}

View File

@ -0,0 +1,33 @@
package sys.thread;
#if (!target.threaded)
#error "This class is not available on this target"
#end
@:coreApi extern class Semaphore {
/**
Creates a new semaphore with an initial value.
**/
public function new(value:Int):Void;
/**
Locks the semaphore.
If the value of the semaphore is zero, then the thread will block until it is able to lock the semaphore.
If the value is non-zero, it is decreased by one.
**/
public function acquire():Void;
/**
Try to lock the semaphore.
If the value of the semaphore is zero, `false` is returned, else the value is increased.
If `timeout` is specified, this function will block until the thread is able to acquire the semaphore, or the timout expires.
`timeout` is in seconds.
**/
public function tryAcquire(?timeout:Float):Bool;
/**
Release the semaphore.
The value of the semaphore is increased by one.
**/
public function release():Void;
}