소스 검색

Net cleanup

luboslenco 5 일 전
부모
커밋
15813392fa

+ 1 - 1
base/project.js

@@ -111,7 +111,7 @@ else if (platform == "android") {
 	add_thread_backend("posix");
 	add_gpu_backend("vulkan");
 	project.add_cfiles("sources/backends/android_file_dialog.c");
-	project.add_cfiles("sources/backends/android_http_request.c");
+	project.add_cfiles("sources/backends/android_net.c");
 	project.add_cfiles("sources/backends/android_native_app_glue.c");
 	project.add_define("IRON_ANDROID");
 	project.add_define("IRON_VULKAN");

+ 0 - 9
base/sources/backends/android_http_request.h

@@ -1,9 +0,0 @@
-#pragma once
-
-#include <stdbool.h>
-
-typedef void (*iron_http_callback_t)(int error, int response, const char *body, void *callbackdata);
-
-void iron_http_request(const char *url, const char *path, const char *data, int port, bool secure, int method, const char *header,
-					   iron_http_callback_t callback, void *callbackdata);
-

+ 9 - 7
base/sources/backends/android_http_request.c → base/sources/backends/android_net.c

@@ -1,13 +1,14 @@
-#include "android_http_request.h"
+
 #include <iron_system.h>
-#include <jni.h>
+#include <iron_net.h>
 #include <string.h>
+#include <jni.h>
 #include "android_native_app_glue.h"
 
 ANativeActivity *iron_android_get_activity(void);
 jclass iron_android_find_class(JNIEnv *env, const char *name);
 
-void iron_http_request(const char *url, const char *path, const char *data, int port, bool secure, int method, const char *header,
+void iron_https_request(const char *url_base, const char *url_path, const char *data, int port, int method,
                        iron_http_callback_t callback, void *callbackdata) {
     ANativeActivity *activity = iron_android_get_activity();
     JNIEnv *env;
@@ -15,11 +16,12 @@ void iron_http_request(const char *url, const char *path, const char *data, int
     (*vm)->AttachCurrentThread(vm, &env, NULL);
     jclass activityClass = iron_android_find_class(env, "arm.AndroidHttpRequest");
 
-    jstring jstr = (*env)->NewStringUTF(env, url);
-    jbyteArray bytes_array = (jbyteArray)((*env)->CallStaticObjectMethod(env, activityClass, (*env)->GetStaticMethodID(env, activityClass, "androidHttpRequest", "(Ljava/lang/String;)[B"), jstr));
+    jstring jurl_base = (*env)->NewStringUTF(env, url_base);
+    jstring jurl_path = (*env)->NewStringUTF(env, url_path);
+    jbyteArray bytes_array = (jbyteArray)((*env)->CallStaticObjectMethod(env, activityClass, (*env)->GetStaticMethodID(env, activityClass, "androidHttpRequest", "(Ljava/lang/String;Ljava/lang/String;)[B"), jurl_base, jurl_path));
 
     if (bytes_array == NULL) {
-        callback(0, 200, NULL, callbackdata);
+        callback(NULL, callbackdata);
         (*vm)->DetachCurrentThread(vm);
         return;
     }
@@ -27,7 +29,7 @@ void iron_http_request(const char *url, const char *path, const char *data, int
     jsize num_bytes = (*env)->GetArrayLength(env, bytes_array);
     jbyte *elements = (*env)->GetByteArrayElements(env, bytes_array, NULL);
     if (elements != NULL) {
-        callback(0, 200, (char *)elements, callbackdata);
+        callback((char *)elements, callbackdata);
         // (*env)->ReleaseByteArrayElements(env, bytes_array, elements, JNI_ABORT);
     }
 

+ 7 - 22
base/sources/backends/apple_net.m

@@ -4,48 +4,33 @@
 
 static NSURLSession *session = nil;
 
-void iron_http_request(const char *url, const char *path, const char *data, int port, bool secure, int method, const char *header,
-                       iron_http_callback_t callback, void *callbackdata) {
+void iron_https_request(const char *url_base, const char *url_path, const char *data, int port, int method,
+                        iron_http_callback_t callback, void *callbackdata) {
 	if (session == nil) {
 		NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
 		session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
 	}
 
-	NSString *urlstring = secure ? @"https://" : @"http://";
-	urlstring = [urlstring stringByAppendingString:[NSString stringWithUTF8String:url]];
+	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:path]];
+	urlstring = [urlstring stringByAppendingString:[NSString stringWithUTF8String:url_path]];
 	NSURL *aUrl = [NSURL URLWithString:urlstring];
 	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl];
 	if (data != 0) {
 		NSString *datastring = [NSString stringWithUTF8String:data];
 		request.HTTPBody = [datastring dataUsingEncoding:NSUTF8StringEncoding];
 	}
-
-	switch (method) {
-	case IRON_HTTP_GET:
-		request.HTTPMethod = @"GET";
-		break;
-	case IRON_HTTP_POST:
-		request.HTTPMethod = @"POST";
-		break;
-	case IRON_HTTP_PUT:
-		request.HTTPMethod = @"PUT";
-		break;
-	case IRON_HTTP_DELETE:
-		request.HTTPMethod = @"DELETE";
-		break;
-	}
+	request.HTTPMethod = method == IRON_HTTP_GET ? @"GET" : @"POST";
 
 	NSURLSessionDataTask *dataTask = [
 		session dataTaskWithRequest:request
 		completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
 			NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
-			int statusCode = (int)[httpResponse statusCode];
 			dispatch_async(dispatch_get_main_queue(), ^{
-				callback(error ? 1 : 0, statusCode, (const char *)[data bytes], callbackdata);
+				callback((const char *)[data bytes], callbackdata);
 			});
 		}
 	];

+ 2 - 2
base/sources/backends/data/android_java/org/armory3d/AndroidHttpRequest.java

@@ -10,10 +10,10 @@ import androidx.annotation.Keep;
 class AndroidHttpRequest {
 
 	@Keep
-	public static byte[] androidHttpRequest(String address) throws Exception {
+	public static byte[] androidHttpRequest(String url_base, String url_path) throws Exception {
 		try {
 			// https://developer.android.com/reference/java/net/HttpURLConnection.html
-			URL url = new URL(address);
+			URL url = new URL(url_base + "/" + url_path);
 			HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
 			InputStream in = new BufferedInputStream(urlConnection.getInputStream());
 

+ 7 - 8
base/sources/backends/posix_net.c

@@ -11,11 +11,11 @@ static SSL_CTX *ctx = NULL;
 static char *buf = NULL;
 static int buf_len = 1024 * 1024;
 
-void iron_http_request(const char *url, const char *path, const char *data, int port, bool secure, int method, const char *header,
-					   iron_http_callback_t callback, void *callbackdata) {
+void iron_https_request(const char *url_base, const char *url_path, const char *data, int port, int method,
+					    iron_http_callback_t callback, void *callbackdata) {
 
 	int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
-	struct hostent *server = gethostbyname(url);
+	struct hostent *server = gethostbyname(url_base);
 	struct sockaddr_in server_addr = {0};
 	server_addr.sin_family = AF_INET;
 	memmove(&server_addr.sin_addr.s_addr, server->h_addr_list[0], server->h_length);
@@ -23,7 +23,7 @@ void iron_http_request(const char *url, const char *path, const char *data, int
 
 	if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
 		close(sock_fd);
-		callback(1, 0, NULL, callbackdata);
+		callback(NULL, callbackdata);
 		return;
 	}
 
@@ -37,13 +37,13 @@ void iron_http_request(const char *url, const char *path, const char *data, int
 	if (SSL_connect(ssl) <= 0) {
 		SSL_free(ssl);
 		close(sock_fd);
-		callback(1, 0, NULL, callbackdata);
+		callback(NULL, callbackdata);
 		return;
 	}
 
 	// For HTTP/1.1, implement "transfer-encoding: chunked"
 	char request[1024];
-	int request_len = snprintf(request, sizeof(request), "GET /%s HTTP/1.0\r\nHost: %s:%d\r\nConnection: close\r\n\r\n", path, url, port);
+	int request_len = snprintf(request, sizeof(request), "GET /%s HTTP/1.0\r\nHost: %s:%d\r\nConnection: close\r\n\r\n", url_path, url_base, port);
 	SSL_write(ssl, request, request_len);
 
 	// Read
@@ -61,11 +61,10 @@ void iron_http_request(const char *url, const char *path, const char *data, int
 	}
 
 	// Parse
-	int status_code = 0;
 	const char *body_ptr = "";
 	char *headers_end = strstr(buf, "\r\n\r\n");
 	body_ptr = headers_end + 4;
-	callback(0, status_code, body_ptr, callbackdata);
+	callback(body_ptr, callbackdata);
 
 	SSL_free(ssl);
 	close(sock_fd);

+ 9 - 27
base/sources/backends/windows_net.c

@@ -5,25 +5,11 @@
 #include <Windows.h>
 #include <winhttp.h>
 
-static const wchar_t *convert(int method) {
-	switch (method) {
-	case IRON_HTTP_GET:
-	default:
-		return L"GET";
-	case IRON_HTTP_POST:
-		return L"POST";
-	case IRON_HTTP_PUT:
-		return L"PUT";
-	case IRON_HTTP_DELETE:
-		return L"DELETE";
-	}
-}
-
 static char *returnData = NULL;
 static int returnDataSize = 0;
 
-void iron_http_request(const char *url, const char *path, const char *data, int port, bool secure, int method, const char *header,
-                       iron_http_callback_t callback, void *callbackdata) {
+void iron_https_request(const char *url_base, const char *url_path, const char *data, int port, int method,
+                        iron_http_callback_t callback, void *callbackdata) {
 	// based on https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttp-sessions-overview
 
 	HINTERNET hSession = WinHttpOpen(L"WinHTTP via Iron/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
@@ -31,27 +17,23 @@ void iron_http_request(const char *url, const char *path, const char *data, int
 	HINTERNET hConnect = NULL;
 	if (hSession) {
 		wchar_t wurl[4096];
-		MultiByteToWideChar(CP_UTF8, 0, url, -1, wurl, 4096);
+		MultiByteToWideChar(CP_UTF8, 0, url_base, -1, wurl, 4096);
 		hConnect = WinHttpConnect(hSession, wurl, port, 0);
 	}
 
 	HINTERNET hRequest = NULL;
 	if (hConnect) {
-		wchar_t wpath[4096];
-		MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, 4096);
+		wchar_t wurl_path[4096];
+		MultiByteToWideChar(CP_UTF8, 0, url_path, -1, wurl_path, 4096);
 		hRequest =
-		    WinHttpOpenRequest(hConnect, convert(method), wpath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, secure ? WINHTTP_FLAG_SECURE : 0);
+		    WinHttpOpenRequest(hConnect, method == IRON_HTTP_GET ? L"GET" : L"POST", wurl_path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
 	}
 
 	BOOL bResults = FALSE;
 
 	if (hRequest) {
-		wchar_t wheader[4096];
-		if (header) {
-			MultiByteToWideChar(CP_UTF8, 0, header, -1, wheader, 4096);
-		}
 		DWORD optionalLength = (data != 0 && strlen(data) > 0) ? (DWORD)strlen(data) : 0;
-		bResults = WinHttpSendRequest(hRequest, header == 0 ? WINHTTP_NO_ADDITIONAL_HEADERS : wheader, header == 0 ? 0 : -1L,
+		bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
 		                              data == 0 ? WINHTTP_NO_REQUEST_DATA : (LPVOID)data, optionalLength, optionalLength, 0);
 	}
 
@@ -86,7 +68,7 @@ void iron_http_request(const char *url, const char *path, const char *data, int
 		} while (dwSize > 0);
 	}
 	else {
-		callback(1, 404, NULL, callbackdata);
+		callback(NULL, callbackdata);
 		return;
 	}
 
@@ -106,5 +88,5 @@ void iron_http_request(const char *url, const char *path, const char *data, int
 		WinHttpCloseHandle(hSession);
 	}
 
-	callback(0, 200, returnData, callbackdata);
+	callback(returnData, callbackdata);
 }

+ 11 - 16
base/sources/iron.h

@@ -327,7 +327,6 @@ string_t *iron_get_arg(i32 index) {
 #include <nfd.h>
 #elif defined(IRON_ANDROID)
 #include "backends/android_file_dialog.h"
-#include "backends/android_http_request.h"
 #elif defined(IRON_IOS)
 #include <wchar.h>
 #include "backends/ios_file_dialog.h"
@@ -1373,7 +1372,7 @@ typedef struct _callback_data {
 	void (*func)(char *, buffer_t *);
 } _callback_data_t;
 
-void _http_callback(int error, int response, const char *body, void *callback_data) {
+void _http_callback(const char *body, void *callback_data) {
 	_callback_data_t *cbd = (_callback_data_t *)callback_data;
 	buffer_t *buffer = NULL;
 	if (body != NULL) {
@@ -1385,7 +1384,7 @@ void _http_callback(int error, int response, const char *body, void *callback_da
 	free(cbd);
 }
 
-void _iron_http_request(string_t *url, i32 size, void (*callback)(char *, buffer_t *)) {
+void iron_file_download(string_t *url, void (*callback)(char *, buffer_t *), i32 size) {
 	_callback_data_t *cbd = malloc(sizeof(_callback_data_t));
 	cbd->size = size;
 	strcpy(cbd->url, url);
@@ -1393,31 +1392,27 @@ void _iron_http_request(string_t *url, i32 size, void (*callback)(char *, buffer
 
 	char url_base[512];
 	char url_path[512];
-	const char *curl = url;
 	int i = 0;
-	for (; i < strlen(curl) - 8; ++i) {
-		if (curl[i + 8] == '/') {
+	for (; i < strlen(url) - 8; ++i) {
+		if (url[i + 8] == '/') {
 			break;
 		}
-		url_base[i] = curl[i + 8]; // Strip https://
+		url_base[i] = url[i + 8]; // Strip https://
 	}
 	url_base[i] = 0;
 	int j = 0;
-	if (strlen(url_base) < strlen(curl) - 8) {
+	if (strlen(url_base) < strlen(url) - 8) {
 		++i; // Skip /
 	}
-	for (; j < strlen(curl) - 8 - i; ++j) {
-		if (curl[i + 8 + j] == 0) {
+	for (; j < strlen(url) - 8 - i; ++j) {
+		if (url[i + 8 + j] == 0) {
 			break;
 		}
-		url_path[j] = curl[i + 8 + j];
+		url_path[j] = url[i + 8 + j];
 	}
 	url_path[j] = 0;
-	#ifdef IRON_ANDROID
-	iron_http_request(curl, url_path, NULL, 443, true, 0, NULL, &_http_callback, cbd);
-	#else
-	iron_http_request(url_base, url_path, NULL, 443, true, 0, NULL, &_http_callback, cbd);
-	#endif
+
+	iron_https_request(url_base, url_path, NULL, 443, 0, &_http_callback, cbd);
 }
 
 bool _window_close_callback(void *data) {

+ 3 - 584
base/sources/iron_net.h

@@ -5,589 +5,8 @@
 
 #define IRON_HTTP_GET 0
 #define IRON_HTTP_POST 1
-#define IRON_HTTP_PUT 2
-#define IRON_HTTP_DELETE 3
 
-typedef void (*iron_http_callback_t)(int error, int response, const char *body, void *callbackdata);
+typedef void (*iron_http_callback_t)(const char *body, void *callbackdata);
 
-void iron_http_request(const char *url, const char *path, const char *data, int port, bool secure, int method, const char *header,
-                                 iron_http_callback_t callback, void *callbackdata);
-
-// typedef enum iron_socket_protocol {
-// 	IRON_SOCKET_PROTOCOL_UDP,
-// 	IRON_SOCKET_PROTOCOL_TCP
-// } iron_socket_protocol_t;
-
-// typedef enum iron_socket_family {
-// 	IRON_SOCKET_FAMILY_IP4,
-// 	IRON_SOCKET_FAMILY_IP6
-// } iron_socket_family_t;
-
-// #ifdef IRON_WINDOWS
-// typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
-// typedef UINT_PTR SOCKET;
-// #endif
-
-// typedef struct iron_socket {
-// #ifdef IRON_WINDOWS
-// 	SOCKET handle;
-// #else
-// 	int handle;
-// #endif
-// 	uint32_t host;
-// 	uint32_t port;
-// 	iron_socket_protocol_t protocol;
-// 	iron_socket_family_t family;
-// 	bool connected;
-// } iron_socket_t;
-
-// typedef struct iron_socket_options {
-// 	bool non_blocking;
-// 	bool broadcast;
-// 	bool tcp_no_delay;
-// } iron_socket_options_t;
-
-// void iron_socket_options_set_defaults(iron_socket_options_t *options);
-// void iron_socket_init(iron_socket_t *socket);
-// bool iron_socket_set(iron_socket_t *socket, const char *host, int port, iron_socket_family_t family, iron_socket_protocol_t protocol);
-// void iron_socket_destroy(iron_socket_t *socket);
-// bool iron_socket_open(iron_socket_t *socket, iron_socket_options_t *options);
-// bool iron_socket_select(iron_socket_t *socket, uint32_t waittime, bool read, bool write);
-
-// /*Typically these are server actions.*/
-// bool iron_socket_bind(iron_socket_t *socket);
-// bool iron_socket_listen(iron_socket_t *socket, int backlog);
-// bool iron_socket_accept(iron_socket_t *socket, iron_socket_t *new_socket, unsigned *remote_address, unsigned *remote_port);
-
-// /*Typically this is a client action.*/
-// bool iron_socket_connect(iron_socket_t *socket);
-
-// int iron_socket_send(iron_socket_t *socket, const uint8_t *data, int size);
-// int iron_socket_send_address(iron_socket_t *socket, unsigned address, int port, const uint8_t *data, int size);
-// int iron_socket_send_url(iron_socket_t *socket, const char *url, int port, const uint8_t *data, int size);
-// int iron_socket_receive(iron_socket_t *socket, uint8_t *data, int maxSize, unsigned *from_address, unsigned *from_port);
-
-// unsigned iron_url_to_int(const char *url, int port);
-
-// #ifdef IRON_IMPLEMENTATION_ROOT
-// #define IRON_IMPLEMENTATION
-// #endif
-
-// #ifdef IRON_IMPLEMENTATION
-
-// #undef IRON_IMPLEMENTATION
-// #include <stb_sprintf.h>
-// #include <iron_system.h>
-// #define IRON_IMPLEMENTATION
-
-// #include <errno.h>
-// #include <stdbool.h>
-// #include <stdio.h>
-// #include <string.h>
-
-// #if defined(IRON_WINDOWS)
-
-// // Windows 7
-// #define WINVER 0x0601
-// #define _WIN32_WINNT 0x0601
-
-// #define NOATOM
-// #define NOCLIPBOARD
-// #define NOCOLOR
-// #define NOCOMM
-// #define NOCTLMGR
-// #define NODEFERWINDOWPOS
-// #define NODRAWTEXT
-// #define NOGDI
-// #define NOGDICAPMASKS
-// #define NOHELP
-// #define NOICONS
-// #define NOKANJI
-// #define NOKEYSTATES
-// #define NOMB
-// #define NOMCX
-// #define NOMEMMGR
-// #define NOMENUS
-// #define NOMETAFILE
-// #define NOMINMAX
-// #define NOMSG
-// #define NONLS
-// #define NOOPENFILE
-// #define NOPROFILER
-// #define NORASTEROPS
-// #define NOSCROLL
-// #define NOSERVICE
-// #define NOSHOWWINDOW
-// #define NOSOUND
-// #define NOSYSCOMMANDS
-// #define NOSYSMETRICS
-// #define NOTEXTMETRIC
-// #define NOUSER
-// #define NOVIRTUALKEYCODES
-// #define NOWH
-// #define NOWINMESSAGES
-// #define NOWINOFFSETS
-// #define NOWINSTYLES
-// #define WIN32_LEAN_AND_MEAN
-
-// #include <Ws2tcpip.h>
-// #include <winsock2.h>
-// #elif defined(IRON_POSIX)
-// #include <arpa/inet.h> // for inet_addr()
-// #include <ctype.h>
-// #include <fcntl.h>
-// #include <netdb.h>
-// #include <netinet/in.h>
-// #include <netinet/tcp.h>
-// #include <string.h>
-// #include <sys/socket.h>
-// #include <unistd.h>
-// #endif
-
-// #if defined(IRON_POSIX)
-// #include <sys/select.h>
-// #endif
-
-// static int counter = 0;
-
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// // Important: Must be cleaned with freeaddrinfo(address) later if the result is 0 in order to prevent memory leaks
-// static int resolveAddress(const char *url, int port, struct addrinfo **result) {
-// 	struct addrinfo hints = {0};
-// 	hints.ai_family = AF_INET;
-// 	hints.ai_socktype = SOCK_DGRAM;
-// 	hints.ai_protocol = IPPROTO_UDP;
-
-// 	char serv[6];
-// 	sprintf(serv, "%u", port);
-
-// 	return getaddrinfo(url, serv, &hints, result);
-// }
-// #endif
-
-// bool iron_socket_bind(iron_socket_t *sock) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	struct sockaddr_in address;
-// 	address.sin_family = sock->family == IRON_SOCKET_FAMILY_IP4 ? AF_INET : AF_INET6;
-// 	address.sin_addr.s_addr = sock->host;
-// 	address.sin_port = sock->port;
-// 	if (bind(sock->handle, (const struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0) {
-// 		iron_error("Could not bind socket: %s", strerror(errno));
-// 		return false;
-// 	}
-// 	return true;
-// #else
-// 	return false;
-// #endif
-// }
-
-// void iron_socket_options_set_defaults(iron_socket_options_t *options) {
-// 	options->non_blocking = true;
-// 	options->broadcast = false;
-// 	options->tcp_no_delay = false;
-// }
-
-// void iron_socket_init(iron_socket_t *sock) {
-// 	sock->handle = 0;
-
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	sock->host = INADDR_ANY;
-// 	sock->port = htons((unsigned short)8080);
-// 	sock->protocol = IRON_SOCKET_PROTOCOL_TCP;
-// 	sock->family = IRON_SOCKET_FAMILY_IP4;
-// #endif
-// 	sock->connected = false;
-
-// #if defined(IRON_WINDOWS)
-// 	if (counter == 0) {
-// 		WSADATA WsaData;
-// 		WSAStartup(MAKEWORD(2, 2), &WsaData);
-// 	}
-// #endif
-// 	++counter;
-// }
-
-// bool iron_socket_open(iron_socket_t *sock, struct iron_socket_options *options) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	switch (sock->protocol) {
-// 	case IRON_SOCKET_PROTOCOL_UDP:
-// 		sock->handle = socket(sock->family == IRON_SOCKET_FAMILY_IP4 ? AF_INET : AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
-// 		break;
-// 	case IRON_SOCKET_PROTOCOL_TCP:
-// 		sock->handle = socket(sock->family == IRON_SOCKET_FAMILY_IP4 ? AF_INET : AF_INET6, SOCK_STREAM, IPPROTO_TCP);
-// 		break;
-// 	default:
-// 		iron_error("Unsupported socket protocol.");
-// 		return false;
-// 	}
-
-// 	if (sock->handle <= 0) {
-// 		iron_error("Could not create socket.");
-// #if defined(IRON_WINDOWS)
-// 		int errorCode = WSAGetLastError();
-// 		switch (errorCode) {
-// 		case (WSANOTINITIALISED):
-// 			iron_error("A successful WSAStartup call must occur before using this function.");
-// 			break;
-// 		case (WSAENETDOWN):
-// 			iron_error("The network subsystem or the associated service provider has failed.");
-// 			break;
-// 		case (WSAEAFNOSUPPORT):
-// 			iron_error(
-// 			         "The specified address family is not supported.For example, an application tried to create a socket for the AF_IRDA address "
-// 			         "family but an infrared adapter and device driver is not installed on the local computer.");
-// 			break;
-// 		case (WSAEINPROGRESS):
-// 			iron_error(
-// 			         "A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.");
-// 			break;
-// 		case (WSAEMFILE):
-// 			iron_error("No more socket descriptors are available.");
-// 			break;
-// 		case (WSAEINVAL):
-// 			iron_error(
-// 			         "An invalid argument was supplied.This error is returned if the af parameter is set to AF_UNSPEC and the type and protocol "
-// 			         "parameter are unspecified.");
-// 			break;
-// 		case (WSAENOBUFS):
-// 			iron_error("No buffer space is available.The socket cannot be created.");
-// 			break;
-// 		case (WSAEPROTONOSUPPORT):
-// 			iron_error("The specified protocol is not supported.");
-// 			break;
-// 		case (WSAEPROTOTYPE):
-// 			iron_error("The specified protocol is the wrong type for this socket.");
-// 			break;
-// 		case (WSAEPROVIDERFAILEDINIT):
-// 			iron_error(
-// 			         "The service provider failed to initialize.This error is returned if a layered service provider(LSP) or namespace provider was "
-// 			         "improperly installed or the provider fails to operate correctly.");
-// 			break;
-// 		case (WSAESOCKTNOSUPPORT):
-// 			iron_error("The specified socket type is not supported in this address family.");
-// 			break;
-// 		case (WSAEINVALIDPROVIDER):
-// 			iron_error("The service provider returned a version other than 2.2.");
-// 			break;
-// 		case (WSAEINVALIDPROCTABLE):
-// 			iron_error("The service provider returned an invalid or incomplete procedure table to the WSPStartup.");
-// 			break;
-// 		default:
-// 			iron_error("Unknown error.");
-// 		}
-// #elif defined(IRON_POSIX)
-// 		iron_error("%s", strerror(errno));
-// #endif
-// 		return false;
-// 	}
-// #endif
-
-// 	if (options) {
-// 		if (options->non_blocking) {
-// #if defined(IRON_WINDOWS)
-// 			DWORD value = 1;
-// 			if (ioctlsocket(sock->handle, FIONBIO, &value) != 0) {
-// 				iron_error("Could not set non-blocking mode.");
-// 				return false;
-// 			}
-// #elif defined(IRON_POSIX)
-// 			int value = 1;
-// 			if (fcntl(sock->handle, F_SETFL, O_NONBLOCK, value) == -1) {
-// 				iron_error("Could not set non-blocking mode.");
-// 				return false;
-// 			}
-// #endif
-// 		}
-
-// 		if (options->broadcast) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 			int value = 1;
-// 			if (setsockopt(sock->handle, SOL_SOCKET, SO_BROADCAST, (const char *)&value, sizeof(value)) < 0) {
-// 				iron_error("Could not set broadcast mode.");
-// 				return false;
-// 			}
-// #endif
-// 		}
-
-// 		if (options->tcp_no_delay) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 			int value = 1;
-// 			if (setsockopt(sock->handle, IPPROTO_TCP, TCP_NODELAY, (const char *)&value, sizeof(value)) != 0) {
-// 				iron_error("Could not set no-delay mode.");
-// 				return false;
-// 			}
-// #endif
-// 		}
-// 	}
-
-// 	return true;
-// }
-
-// void iron_socket_destroy(iron_socket_t *sock) {
-// #if defined(IRON_WINDOWS)
-// 	closesocket(sock->handle);
-// #elif defined(IRON_POSIX)
-// 	close(sock->handle);
-// #endif
-
-// 	memset(sock, 0, sizeof(iron_socket_t));
-
-// 	--counter;
-// #if defined(IRON_WINDOWS)
-// 	if (counter == 0) {
-// 		WSACleanup();
-// 	}
-// #endif
-// }
-
-// bool iron_socket_select(iron_socket_t *sock, uint32_t waittime, bool read, bool write) {
-// #if (defined(IRON_WINDOWS) || defined(IRON_POSIX))
-// 	fd_set r_fds, w_fds;
-// 	struct timeval timeout;
-
-// 	FD_ZERO(&r_fds);
-// 	FD_ZERO(&w_fds);
-
-// 	FD_SET(sock->handle, &r_fds);
-// 	FD_SET(sock->handle, &w_fds);
-
-// 	timeout.tv_sec = waittime;
-// 	timeout.tv_usec = 0;
-
-// 	if (select(0, &r_fds, &w_fds, NULL, &timeout) < 0) {
-// 		iron_error("iron_socket_select didn't work: %s", strerror(errno));
-// 		return false;
-// 	}
-
-// 	if (read && write) {
-// 		return FD_ISSET(sock->handle, &w_fds) && FD_ISSET(sock->handle, &r_fds);
-// 	}
-// 	else if (read) {
-// 		return FD_ISSET(sock->handle, &r_fds);
-// 	}
-// 	else if (write) {
-// 		return FD_ISSET(sock->handle, &w_fds);
-// 	}
-// 	else {
-// 		iron_error("Calling iron_socket_select with both read and write set to false is useless.");
-// 		return false;
-// 	}
-// #else
-// 	return false;
-// #endif
-// }
-
-// bool iron_socket_set(iron_socket_t *sock, const char *host, int port, iron_socket_family_t family, iron_socket_protocol_t protocol) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-
-// 	sock->family = family;
-// 	sock->protocol = protocol;
-// 	sock->port = htons((unsigned short)port);
-
-// 	if (host == NULL)
-// 		return true;
-
-// 	if (isdigit(host[0]) || (family == IRON_SOCKET_FAMILY_IP6 && host[4] == ':')) { // Is IPv4 or IPv6 string
-// 		struct in_addr addr;
-
-// 		if (inet_pton(sock->family == IRON_SOCKET_FAMILY_IP4 ? AF_INET : AF_INET6, host, &addr) == 0) {
-// 			iron_error("Invalid %s address: %s\n", sock->family == IRON_SOCKET_FAMILY_IP4 ? "IPv4" : "IPv6", host);
-// 			return false;
-// 		}
-// 		sock->host = addr.s_addr;
-// 		return true;
-// 	}
-// 	else {
-// 		struct addrinfo *address = NULL;
-// 		int res = resolveAddress(host, port, &address);
-// 		if (res != 0) {
-// 			iron_error("Could not resolve address.");
-// 			return false;
-// 		}
-// #if defined(IRON_POSIX)
-// 		sock->host = ((struct sockaddr_in *)address->ai_addr)->sin_addr.s_addr;
-// #else
-// 		sock->host = ((struct sockaddr_in *)address->ai_addr)->sin_addr.S_un.S_addr;
-// #endif
-// 		freeaddrinfo(address);
-
-// 		return true;
-// 	}
-// #else
-// 	return false;
-// #endif
-// }
-
-// bool iron_socket_listen(iron_socket_t *socket, int backlog) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	int res = listen(socket->handle, backlog);
-// 	return (res == 0);
-// #else
-// 	return false;
-// #endif
-// }
-
-// bool iron_socket_accept(iron_socket_t *sock, iron_socket_t *newSocket, unsigned *remoteAddress, unsigned *remotePort) {
-// #if defined(IRON_WINDOWS)
-// 	typedef int socklen_t;
-// #endif
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	struct sockaddr_in addr;
-// 	socklen_t addrLength = sizeof(addr);
-// 	newSocket->handle = accept(sock->handle, (struct sockaddr *)&addr, &addrLength);
-// 	if (newSocket->handle <= 0) {
-// 		return false;
-// 	}
-
-// 	newSocket->connected = sock->connected = true;
-// 	newSocket->host = addr.sin_addr.s_addr;
-// 	newSocket->port = addr.sin_port;
-// 	newSocket->family = sock->family;
-// 	newSocket->protocol = sock->protocol;
-// 	*remoteAddress = ntohl(addr.sin_addr.s_addr);
-// 	*remotePort = ntohs(addr.sin_port);
-// 	return true;
-// #else
-// 	return false;
-// #endif
-// }
-
-// bool iron_socket_connect(iron_socket_t *sock) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	struct sockaddr_in addr;
-// 	addr.sin_family = sock->family == IRON_SOCKET_FAMILY_IP4 ? AF_INET : AF_INET6;
-// 	addr.sin_addr.s_addr = sock->host;
-// 	addr.sin_port = sock->port;
-
-// 	int res = connect(sock->handle, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-// 	return sock->connected = (res == 0);
-// #else
-// 	return false;
-// #endif
-// }
-
-// int iron_socket_send(iron_socket_t *sock, const uint8_t *data, int size) {
-// #if defined(IRON_WINDOWS)
-// 	typedef int socklen_t;
-// #endif
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	if (sock->protocol == IRON_SOCKET_PROTOCOL_UDP) {
-// 		struct sockaddr_in addr;
-// 		addr.sin_family = sock->family == IRON_SOCKET_FAMILY_IP4 ? AF_INET : AF_INET6;
-// 		addr.sin_addr.s_addr = sock->host;
-// 		addr.sin_port = sock->port;
-
-// 		size_t sent = sendto(sock->handle, (const char *)data, size, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-// 		if (sent != size) {
-// 			iron_error("Could not send packet.");
-// 			return -1;
-// 		}
-// 		return (int)sent;
-// 	}
-// 	else {
-// 		if (!sock->connected) {
-// 			iron_error("Call iron_sockect_connect/bind before send/recv can be called for TCP sockets.");
-// 			return -1;
-// 		}
-
-// 		size_t sent = send(sock->handle, (const char *)data, size, 0);
-// 		if (sent != size) {
-// 			iron_error("Could not send packet.");
-// 		}
-// 		return (int)sent;
-// 	}
-// #else
-// 	return 0;
-// #endif
-// }
-
-// int iron_socket_send_address(iron_socket_t *sock, unsigned address, int port, const uint8_t *data, int size) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	struct sockaddr_in addr;
-// 	addr.sin_family = AF_INET;
-// 	addr.sin_addr.s_addr = htonl(address);
-// 	addr.sin_port = htons(port);
-
-// 	size_t sent = sendto(sock->handle, (const char *)data, size, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-// 	if (sent != size) {
-// 		iron_error("Could not send packet.");
-// 	}
-// 	return (int)sent;
-// #else
-// 	return 0;
-// #endif
-// }
-
-// int iron_socket_send_url(iron_socket_t *sock, const char *url, int port, const uint8_t *data, int size) {
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-// 	struct addrinfo *address = NULL;
-// 	int res = resolveAddress(url, port, &address);
-// 	if (res != 0) {
-// 		iron_error("Could not resolve address.");
-// 		return 0;
-// 	}
-
-// 	size_t sent = sendto(sock->handle, (const char *)data, size, 0, address->ai_addr, sizeof(struct sockaddr_in));
-// 	if (sent != size) {
-// 		iron_error("Could not send packet.");
-// 	}
-// 	freeaddrinfo(address);
-// 	return (int)sent;
-// #else
-// 	return 0;
-// #endif
-// }
-
-// int iron_socket_receive(iron_socket_t *sock, uint8_t *data, int maxSize, unsigned *fromAddress, unsigned *fromPort) {
-// #if defined(IRON_WINDOWS)
-// 	typedef int socklen_t;
-// 	typedef int ssize_t;
-// #endif
-// #if defined(IRON_WINDOWS) || defined(IRON_POSIX)
-
-// 	if (sock->protocol == IRON_SOCKET_PROTOCOL_UDP) {
-// 		struct sockaddr_in from;
-// 		socklen_t fromLength = sizeof(from);
-// 		ssize_t bytes = recvfrom(sock->handle, (char *)data, maxSize, 0, (struct sockaddr *)&from, &fromLength);
-// 		if (bytes <= 0) {
-// 			return (int)bytes;
-// 		}
-// 		*fromAddress = ntohl(from.sin_addr.s_addr);
-// 		*fromPort = ntohs(from.sin_port);
-// 		return (int)bytes;
-// 	}
-// 	else {
-
-// 		if (!sock->connected) {
-// 			iron_error("Call iron_sockect_connect/bind before send/recv can be called for TCP sockets.");
-// 			return -1;
-// 		}
-// 		ssize_t bytes = recv(sock->handle, (char *)data, maxSize, 0);
-// 		*fromAddress = ntohl(sock->host);
-// 		*fromPort = ntohs(sock->port);
-// 		return (int)bytes;
-// 	}
-// #else
-// 	return 0;
-// #endif
-// }
-
-// unsigned iron_url_to_int(const char *url, int port) {
-// #if defined(IRON_WINDOWS)
-// 	struct addrinfo *address = NULL;
-// 	int res = resolveAddress(url, port, &address);
-// 	if (res != 0) {
-// 		iron_error("Could not resolve address.");
-// 		return -1;
-// 	}
-
-// 	unsigned fromAddress = ntohl(((struct sockaddr_in *)address->ai_addr)->sin_addr.S_un.S_addr);
-// 	freeaddrinfo(address);
-
-// 	return fromAddress;
-// #else
-// 	return 0;
-// #endif
-// }
-
-// #endif
+void iron_https_request(const char *url_base, const char *url_path, const char *data, int port, int method,
+                        iron_http_callback_t callback, void *callbackdata);

+ 9 - 35
base/sources/ts/file.ts

@@ -1,12 +1,6 @@
 
 type file_download_data_t = {
-	dst_path: string;
-	done: (url: string)=>void;
-};
-
-type file_download_bytes_data_t = {
-	url: string;
-	save: string;
+	path: string;
 	done: (url: string, ab: buffer_t)=>void;
 };
 
@@ -17,7 +11,6 @@ type file_cache_cloud_data_t = {
 };
 
 let _file_download_map: map_t<string, file_download_data_t> = map_create();
-let _file_download_bytes_map: map_t<string, file_download_bytes_data_t> = map_create();
 let _file_cache_cloud_map: map_t<string, file_cache_cloud_data_t> = map_create();
 
 ///if arm_windows
@@ -94,35 +87,16 @@ function file_start(path: string) {
 	///end
 }
 
-function file_download(url: string, dst_path: string, done: (url: string)=>void, size: i32 = 0) {
-	let fdd: file_download_data_t = { dst_path: dst_path, done: done };
+function file_download_to(url: string, dst_path: string, done: (url: string, ab: buffer_t)=>void, size: i32 = 0) {
+	let fdd: file_download_data_t = { path: dst_path, done: done };
 	map_set(_file_download_map, url, fdd);
-	_iron_http_request(url, size, function (url: string, ab: buffer_t) {
+	iron_file_download(url, function (url: string, ab: buffer_t) {
 		let fdd: file_download_data_t = map_get(_file_download_map, url);
 		if (ab != null) {
-			iron_file_save_bytes(fdd.dst_path, ab, 0);
+			iron_file_save_bytes(fdd.path, ab, 0);
 		}
-		fdd.done(url);
-	});
-}
-
-function file_download_bytes(url: string, done: (url: string, ab: buffer_t)=>void) {
-	let save: string;
-	if (path_is_protected()) {
-		save = iron_internal_save_path();
-	}
-	else {
-		save = path_data() + path_sep;
-	}
-	save += "download.bin";
-
-	let fdbd: file_download_bytes_data_t = { url: url, save: save, done: done };
-	map_set(_file_download_bytes_map, url, fdbd);
-	file_download(url, save, function (url: string) {
-		let fdbd: file_download_bytes_data_t = map_get(_file_download_bytes_map, url);
-		let buffer: buffer_t = iron_load_blob(fdbd.save);
-		fdbd.done(fdbd.url, buffer);
-	});
+		fdd.done(url, ab);
+	}, size);
 }
 
 function file_cache_cloud(path: string, done: (s: string)=>void) {
@@ -164,7 +138,7 @@ function file_cache_cloud(path: string, done: (s: string)=>void) {
 	let fccd: file_cache_cloud_data_t = { dest: dest, path: path, done: done };
 	map_set(_file_cache_cloud_map, url, fccd);
 
-	file_download(url, dest, function (url: string) {
+	file_download_to(url, dest, function (url: string) {
 		let fccd: file_cache_cloud_data_t = map_get(_file_cache_cloud_map, url);
 		if (!iron_file_exists(fccd.dest)) {
 			console_error(strings_check_internet_connection());
@@ -189,7 +163,7 @@ function file_cache_cloud(path: string, done: (s: string)=>void) {
 
 function file_init_cloud_bytes(done: ()=>void, append: string = "") {
 	_file_init_cloud_bytes_done = done;
-	file_download_bytes(config_raw.server + "/?list-type=2" + append, function (url: string, buffer: buffer_t) {
+	iron_file_download(config_raw.server + "/?list-type=2" + append, function (url: string, buffer: buffer_t) {
 		if (buffer == null) {
 			let empty: string[] = [];
 			map_set(file_cloud, "cloud", empty);

+ 1 - 1
base/sources/ts/iron.ts

@@ -286,7 +286,7 @@ declare function iron_internal_save_path(): string;
 declare function iron_get_arg_count(): i32;
 declare function iron_get_arg(index: i32): string;
 declare function iron_get_files_location(): string;
-declare function _iron_http_request(url: string, size: i32, callback: (url: string, _: buffer_t)=>void): void;
+declare function iron_file_download(url: string, callback: (url: string, _: buffer_t)=>void, size: i32 = 0): void;
 
 declare function draw_init(image_vert: buffer_t, image_frag: buffer_t, image_transform_vert: buffer_t, image_transform_frag: buffer_t, rect_vert: buffer_t, rect_frag: buffer_t, tris_vert: buffer_t, tris_frag: buffer_t, text_vert: buffer_t, text_frag: buffer_t): void;
 declare function draw_begin(render_target: gpu_texture_t = null, clear: bool = false, color: u32 = 0): void;

+ 1 - 1
paint/sources/translator.ts

@@ -119,7 +119,7 @@ function translator_load_translations(new_locale: string) {
 		_translator_load_translations_cjk_font_disk_path += "font_cjk.ttc";
 
 		if (!iron_file_exists(_translator_load_translations_cjk_font_disk_path)) {
-			file_download("https://github.com/armory3d/armorbase/raw/main/Assets/common/extra/font_cjk.ttc", _translator_load_translations_cjk_font_disk_path, function () {
+			file_download_to("https://github.com/armory3d/armorbase/raw/main/Assets/common/extra/font_cjk.ttc", _translator_load_translations_cjk_font_disk_path, function () {
 
 				if (!iron_file_exists(_translator_load_translations_cjk_font_disk_path)) {
 					// Fall back to English

+ 1 - 1
paint/sources/ui_menubar.ts

@@ -529,7 +529,7 @@ function ui_menubar_draw_category_items() {
 			iron_load_url(manifest_url_ios);
 			///else
 			// Retrieve latest version number
-			file_download_bytes("https://server.armorpaint.org/" + to_lower_case(manifest_title) + ".html", function (url: string, buffer: buffer_t) {
+			iron_file_download("https://server.armorpaint.org/" + to_lower_case(manifest_title) + ".html", function (url: string, buffer: buffer_t) {
 				if (buffer != null)  {
 					// Compare versions
 					let update: update_info_t = json_parse(sys_buffer_to_string(buffer));