Improve net request on macos

This commit is contained in:
luboslenco
2025-11-20 22:29:42 +01:00
parent c1c1ea32f8
commit 392bbc302c
+80 -34
View File
@@ -1,46 +1,92 @@
#include <iron_net.h>
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
static NSURLSession *session = nil;
volatile uint64_t iron_net_bytes_downloaded = 0;
static NSURLSession *download_session = nil;
@interface IronDownloadDelegate : NSObject <NSURLSessionDownloadDelegate>
@end
@implementation IronDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
iron_net_bytes_downloaded += bytesWritten;
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSString *dstPath = objc_getAssociatedObject(downloadTask, @"dst_path");
if (dstPath) {
NSError *error = nil;
NSURL *destURL = [NSURL fileURLWithPath:dstPath];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:destURL error:&error];
if ([dstPath hasSuffix:@"sd_vulkan"] || [dstPath hasSuffix:@"sd_cpu"]) {
NSDictionary *attrs = @{ NSFilePosixPermissions : @0755 };
NSError *chmodError = nil;
[[NSFileManager defaultManager] setAttributes:attrs ofItemAtPath:dstPath error:&chmodError];
}
}
else {
NSData *fileData = [NSData dataWithContentsOfURL:location options:NSDataReadingMappedIfSafe error:nil];
NSMutableData *memoryData = objc_getAssociatedObject(downloadTask, @"memoryData");
[memoryData appendData:fileData];
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSURLSessionDownloadTask *downloadTask = (NSURLSessionDownloadTask *)task;
NSValue *cbVal = objc_getAssociatedObject(task, @"callback");
NSValue *dataVal = objc_getAssociatedObject(task, @"callbackdata");
NSString *dstPath = objc_getAssociatedObject(task, @"dst_path");
NSMutableData *memoryData = objc_getAssociatedObject(task, @"memoryData");
iron_https_callback_t callback = cbVal ? [cbVal pointerValue] : NULL;
void *callbackdata = dataVal ? [dataVal pointerValue] : NULL;
dispatch_async(dispatch_get_main_queue(), ^{
if (dstPath) {
callback(NULL, callbackdata);
}
else {
char *buffer = malloc(memoryData.length + 1);
memcpy(buffer, memoryData.bytes, memoryData.length);
buffer[memoryData.length] = '\0';
callback(buffer, callbackdata);
}
});
}
@end
void iron_net_request(const char *url_base, const char *url_path, const char *data, int port, int method, iron_https_callback_t callback, void *callbackdata, const char *dst_path) {
if (session == nil) {
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
if (!download_session) {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.qualityOfService = NSQualityOfServiceUtility;
static IronDownloadDelegate *delegate = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
delegate = [[IronDownloadDelegate alloc] init];
});
download_session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue];
}
NSString *urlstring = @"https://";
urlstring = [urlstring stringByAppendingString:[NSString stringWithUTF8String:url_base]];
urlstring = [urlstring stringByAppendingString:@":"];
urlstring = [urlstring stringByAppendingString:[[NSNumber numberWithInt:port] stringValue]];
urlstring = [urlstring stringByAppendingString:@"/"];
urlstring = [urlstring stringByAppendingString:[NSString stringWithUTF8String:url_path]];
NSURL *aUrl = [NSURL URLWithString:urlstring];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl];
request.HTTPMethod = method == IRON_HTTPS_GET ? @"GET" : @"POST";
if (data != 0) {
NSString *datastring = [NSString stringWithUTF8String:data];
request.HTTPBody = [datastring dataUsingEncoding:NSUTF8StringEncoding];
}
NSString *urlStr = [NSString stringWithFormat:@"https://%@:%d/%@",
[NSString stringWithUTF8String:url_base],
port,
[NSString stringWithUTF8String:url_path]];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = (method == IRON_HTTPS_GET) ? @"GET" : @"POST";
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
dispatch_async(dispatch_get_main_queue(), ^{
char *b = (char *)[data bytes];
int len = [data length];
char *result = malloc(len + 1);
memcpy(result, b, len);
result[len] = 0;
callback(result, callbackdata);
free(result);
});
}];
[dataTask resume];
NSURLSessionDownloadTask *task = [download_session downloadTaskWithRequest:request];
objc_setAssociatedObject(task, @"callback", [NSValue valueWithPointer:callback], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(task, @"callbackdata", [NSValue valueWithPointer:callbackdata], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(task, @"dst_path", dst_path ? [NSString stringWithUTF8String:dst_path] : nil, OBJC_ASSOCIATION_COPY_NONATOMIC);
if (!dst_path) {
objc_setAssociatedObject(task, @"memoryData", [NSMutableData data], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
[task resume];
}
void iron_net_update() {
}
volatile uint64_t iron_net_bytes_downloaded = 0;