commit 703a562dc80252f42275bd3c2ec934484b980d6b
parent 539143df7a74c3b27ca5a5646dc00876b37f2bfb
Author: Erik Agsjö <erik.agsjo@gmail.com>
Date: Wed, 10 Nov 2021 22:21:21 +0100
Good enough for now
Diffstat:
3 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/naett_internal.h b/naett_internal.h
@@ -62,6 +62,9 @@ typedef struct {
int code;
KVLink* headers;
Buffer body;
+#if __APPLE__
+ id session;
+#endif
} InternalResponse;
void naettPlatformInitRequest(InternalRequest* req);
diff --git a/naett_objc.h b/naett_objc.h
@@ -47,6 +47,9 @@
if (!class_addIvar(CLASS, NAME, SIZE, rint(log2(SIZE)), SIGNATURE)) assert(false)
#define objc_alloc(CLASS) objc_msgSend_id(class(CLASS), sel("alloc"))
+#define autorelease(OBJ) objc_msgSend_void(OBJ, sel("autorelease"))
+#define retain(OBJ) objc_msgSend_void(OBJ, sel("retain"))
+#define release(OBJ) objc_msgSend_void(OBJ, sel("release"))
#if __LP64__ || NS_BUILD_32_LIKE_64
#define NSIntegerEncoding "q"
diff --git a/naett_osx.c b/naett_osx.c
@@ -9,17 +9,24 @@
void naettPlatformInitRequest(InternalRequest* req) {
id urlString = objc_msgSend_t(id, const char*)(class("NSString"), sel("stringWithUTF8String:"), req->url);
id url = objc_msgSend_t(id, id)(class("NSURL"), sel("URLWithString:"), urlString);
+ release(urlString);
+
id request = objc_msgSend_t(id, id)(class("NSMutableURLRequest"), sel("requestWithURL:"), url);
+ release(url);
+
objc_msgSend_t(void, double)(request, sel("setTimeoutInterval:"), (double)(req->options.timeoutMS) / 1000.0);
id methodString =
objc_msgSend_t(id, const char*)(class("NSString"), sel("stringWithUTF8String:"), req->options.method);
objc_msgSend_t(void, id)(request, sel("setHTTPMethod:"), methodString);
+ release(methodString);
KVLink* header = req->options.headers;
while (header != NULL) {
id name = objc_msgSend_t(id, const char*)(class("NSString"), sel("stringWithUTF8String:"), header->key);
id value = objc_msgSend_t(id, const char*)(class("NSString"), sel("stringWithUTF8String:"), header->value);
objc_msgSend_t(void, id, id)(request, sel("setValue:forHTTPHeaderField:"), name, value);
+ release(name);
+ release(value);
header = header->next;
}
@@ -29,6 +36,7 @@ void naettPlatformInitRequest(InternalRequest* req) {
id bodyData = objc_msgSend_t(id, void*, NSUInteger, BOOL)(
class("NSData"), sel("dataWithBytesNoCopy:length:freeWhenDone:"), body->data, body->size, NO);
objc_msgSend_t(void, id)(request, sel("setHTTPBody:"), bodyData);
+ release(bodyData);
}
req->urlRequest = request;
@@ -62,35 +70,51 @@ void didReceiveData(id self, SEL _sel, id session, id dataTask, id data) {
res->request->options.bodyWriter(bytes, length, res->request->options.bodyWriterData);
}
-void didComplete(id self, SEL _sel, id session, id dataTask, id error) {
+static void didComplete(id self, SEL _sel, id session, id dataTask, id error) {
InternalResponse* res = NULL;
object_getInstanceVariable(self, "response", (void**)&res);
res->complete = 1;
}
-void naettPlatformMakeRequest(InternalRequest* req, InternalResponse* res) {
- Class TaskDelegateClass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "TaskDelegate", 0);
- addMethod(TaskDelegateClass, "URLSession:dataTask:didReceiveData:", didReceiveData, "v@:@@@");
- addMethod(TaskDelegateClass, "URLSession:task:didCompleteWithError:", didComplete, "v@:@@@");
- addIvar(TaskDelegateClass, "response", sizeof(void*), "^v");
+static id createDelegate() {
+ Class TaskDelegateClass = nil;
- id config = objc_msgSend_id(class("NSURLSessionConfiguration"), sel("ephemeralSessionConfiguration"));
+ if (!TaskDelegateClass) {
+ TaskDelegateClass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "naettTaskDelegate", 0);
+ addMethod(TaskDelegateClass, "URLSession:dataTask:didReceiveData:", didReceiveData, "v@:@@@");
+ addMethod(TaskDelegateClass, "URLSession:task:didCompleteWithError:", didComplete, "v@:@@@");
+ addIvar(TaskDelegateClass, "response", sizeof(void*), "^v");
+ }
id delegate = objc_msgSend_id((id)TaskDelegateClass, sel("alloc"));
delegate = objc_msgSend_id(delegate, sel("init"));
+ return delegate;
+}
+
+void naettPlatformMakeRequest(InternalRequest* req, InternalResponse* res) {
+ id config = objc_msgSend_id(class("NSURLSessionConfiguration"), sel("ephemeralSessionConfiguration"));
+ id delegate = createDelegate();
+
id session = objc_msgSend_t(id, id, id, id)(
class("NSURLSession"), sel("sessionWithConfiguration:delegate:delegateQueue:"), config, delegate, nil);
- id task = objc_msgSend_t(id, id)(session, sel("dataTaskWithRequest:"), req->urlRequest);
+ res->session = session;
+ release(delegate);
+
+ id task = objc_msgSend_t(id, id)(session, sel("dataTaskWithRequest:"), req->urlRequest);
object_setInstanceVariable(delegate, "response", (void*)res);
objc_msgSend_void(task, sel("resume"));
+ release(task);
}
void naettPlatformFreeRequest(InternalRequest* req) {
+ release(req->urlRequest);
+ req->urlRequest = nil;
}
void naettPlatformCloseResponse(InternalResponse* res) {
+ release(res->session);
}
#endif // __MACOS__