diff --git a/base/project.js b/base/project.js index 6f4cefd6..50a08648 100644 --- a/base/project.js +++ b/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"); diff --git a/base/sources/backends/android_http_request.h b/base/sources/backends/android_http_request.h deleted file mode 100644 index c7605847..00000000 --- a/base/sources/backends/android_http_request.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -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); - diff --git a/base/sources/backends/android_http_request.c b/base/sources/backends/android_net.c similarity index 70% rename from base/sources/backends/android_http_request.c rename to base/sources/backends/android_net.c index 26dc74a7..b32e8163 100644 --- a/base/sources/backends/android_http_request.c +++ b/base/sources/backends/android_net.c @@ -1,13 +1,14 @@ -#include "android_http_request.h" + #include -#include +#include #include +#include #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); } diff --git a/base/sources/backends/apple_net.m b/base/sources/backends/apple_net.m index 6f884f22..6f3c2147 100644 --- a/base/sources/backends/apple_net.m +++ b/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); }); } ]; diff --git a/base/sources/backends/data/android_java/org/armory3d/AndroidHttpRequest.java b/base/sources/backends/data/android_java/org/armory3d/AndroidHttpRequest.java index da5419b3..90844cc3 100644 --- a/base/sources/backends/data/android_java/org/armory3d/AndroidHttpRequest.java +++ b/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()); diff --git a/base/sources/backends/posix_net.c b/base/sources/backends/posix_net.c index b6305b22..abdadb84 100644 --- a/base/sources/backends/posix_net.c +++ b/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); diff --git a/base/sources/backends/windows_net.c b/base/sources/backends/windows_net.c index 0fedb129..1afe6c8d 100644 --- a/base/sources/backends/windows_net.c +++ b/base/sources/backends/windows_net.c @@ -5,25 +5,11 @@ #include #include -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); } diff --git a/base/sources/iron.h b/base/sources/iron.h index 3a45c3a9..73d96780 100644 --- a/base/sources/iron.h +++ b/base/sources/iron.h @@ -327,7 +327,6 @@ string_t *iron_get_arg(i32 index) { #include #elif defined(IRON_ANDROID) #include "backends/android_file_dialog.h" -#include "backends/android_http_request.h" #elif defined(IRON_IOS) #include #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) { diff --git a/base/sources/iron_net.h b/base/sources/iron_net.h index 8f3f5ae9..e8e7e7b3 100644 --- a/base/sources/iron_net.h +++ b/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 -// #include -// #define IRON_IMPLEMENTATION - -// #include -// #include -// #include -// #include - -// #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 -// #include -// #elif defined(IRON_POSIX) -// #include // for inet_addr() -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #endif - -// #if defined(IRON_POSIX) -// #include -// #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); diff --git a/base/sources/ts/file.ts b/base/sources/ts/file.ts index 0af00182..0c3ebb44 100644 --- a/base/sources/ts/file.ts +++ b/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 = map_create(); -let _file_download_bytes_map: map_t = map_create(); let _file_cache_cloud_map: map_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); diff --git a/base/sources/ts/iron.ts b/base/sources/ts/iron.ts index c298a8b4..1610d46a 100644 --- a/base/sources/ts/iron.ts +++ b/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; diff --git a/paint/sources/translator.ts b/paint/sources/translator.ts index 5c1afd89..da151ef8 100644 --- a/paint/sources/translator.ts +++ b/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 diff --git a/paint/sources/ui_menubar.ts b/paint/sources/ui_menubar.ts index 5a0bea7b..eefd94a4 100644 --- a/paint/sources/ui_menubar.ts +++ b/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));