c-smile / sciter-js-sdk

Sciter.JS - Sciter but with QuickJS on board instead of my TIScript
BSD 3-Clause "New" or "Revised" License
1.64k stars 97 forks source link

Linux: Execution locks at 'await fetch(url)' #19

Open jsprog opened 3 years ago

jsprog commented 3 years ago

The fetch example never worked since it was added to the Linux version of sciter.js. The execution always locks at await fetch(url). but it runs successfully under Windows.

Note: I didn't test with arm32

c-smile commented 3 years ago

Seems like libcurl is not installed.

I need to do something with HTTP client on Linux. Windows and MacOS versions use system's HTTP client but Linux is no man's land in this respect.

Seems like I need to link some HTTP client library statically in Linux version, sigh.

jsprog commented 3 years ago

I'm not in a position to give some perfect recommendations. At least, sharing my ideas won't hurt.

According to #10 , There is a possibility to bring libwebsockets to sciter.js. Why not using this to bring the fetch API to Linux.

I'm not sure if it's too low level or it impose many restrictions and thus preventing you from using it for the fetch API. According to the official link, libwebsockets has support for HTTP/1.x and HTTP/2 clients + TLS.

Link for HTTP client examples: https://github.com/warmcat/libwebsockets/tree/main/minimal-examples/http-client

c-smile commented 3 years ago

I don't want to include HTTP client statically into library. Not all use cases require HTTP communication.

c-smile commented 3 years ago

I've added WebSocket support, but note that is quick and possibly dirty implementation on top of tcp, libuv and mbedTLS that is there already. I will probably add also simple fallback http client implementation for Linux, but later. For now run sudo apt install curl

jsprog commented 3 years ago

curl is already installed since a long time and it's succeeding with the links in the fetch sample. Unfortunately, the issue still persists.

Currently, Promises aren't getting rejected to catch the error, but the execution is locked at either:

curl http://www.sciter.com curl http - sciter com

await fetch('http://sciter.com') + await resp.json() await fetch - sciter com

c-smile commented 3 years ago

I do not see problems on Linux (I am using Mint and Raspbian here):

mint fetch

Test is this

<html>
    <head>
        <title>Test</title>
        <style>

plaintext {
  border:1px solid;
  size:*;
}

        </style>
        <script>

var plaintext = document.querySelector("plaintext");

async function getit() {
  try {
    var resp = await fetch("https://sciter.com");
    var data = resp.text();
    plaintext.value = data;
  } catch (e) {
    console.log(e);
  }
}

getit();

        </script>
    </head>
    <body>
      <p>Data received by <code>await fetch(url)</code>:</p>
      <plaintext />
    </body>
</html>

Also note:

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

From https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

In order fetch to work on Linux you will need libcurl 4 .so ( libcurl 3 should work too ):

sudo apt-get install libcurl4 libcurl4-openssl-dev -y

jsprog commented 3 years ago

The catch clause is getting executed. unfortunately, I can't get anything by logging the error and the script can't reach the resp.text() at all.

sciter-https-fetch

libcurl

Not sure if something is wrong with my system, and that's why I'll be updating my packages and if I fail with this, I'll try to use a virtual machine to test with some Linux distributions.

jsprog commented 3 years ago

After system update, I executed these instructions

sudo apt-get remove curl sudo apt-get remove libcurl4 libcurl4-openssl-dev -y

After system reboot

sudo apt-cache search ^libcurl [sudo] password for *****:
libcurl3-gnutls - easy-to-use client-side URL transfer library (GnuTLS flavour) libcurl3-nss - easy-to-use client-side URL transfer library (NSS flavour) libcurl4 - easy-to-use client-side URL transfer library (OpenSSL flavour) libcurl4-doc - documentation for libcurl libcurl4-gnutls-dev - development files and documentation for libcurl (GnuTLS flavour) libcurl4-nss-dev - development files and documentation for libcurl (NSS flavour) libcurl4-openssl-dev - development files and documentation for libcurl (OpenSSL flavour) libghc-hxt-curl-dev - LibCurl interface for HXT libghc-hxt-curl-doc - LibCurl interface for HXT; documentation libghc-hxt-curl-prof - LibCurl interface for HXT; profiling libraries lua-curl - libcURL bindings for the Lua language lua-curl-dev - libcURL development files for the Lua language libcurl-ocaml - OCaml curl bindings (Runtime Library) libcurl-ocaml-dev - OCaml libcurl bindings (Development package) ruby-ethon - libcurl wrapper using ffi

sudo apt-get install curl sudo apt-get install libcurl4 libcurl4-openssl-dev -y

After that, I searched for "libcurl.so" using nemo to discover:

libcurl so

Now, it's time for 'sudo nemo'

I renamed the symbolic links, and tested again to see this message:

ALERT:HTTP: libcurl not found on this machine, http request ignored.

Then I created new symbolic links (ctrl+shift + drag to target folder) with similar names but liked to another file from the vmare installation (there are 2 files and I tested with both of them). I even tested with libcurl.so.4.6.0 from /var/lib/flatpack/..... but I'm always receiving the same message:

ALERT:HTTP: libcurl not found on this machine, http request ignored.

Even curl is failing when basing the new symbolic links on other targets

According to the previous logs intercepted by wireshark, my system is receiving http responses but sciter.js is upgrading to https and failing from that point.

Next time, I'll try to share more after testing with some http (not https) servers. I might even try to bring libcurl.so.4 from other sources. But before that, would you confirm about these:

c-smile commented 3 years ago

Here is how I load libcurl:

    void *handle = dlopen("libcurl.so.4", RTLD_NOW);
    if (!handle) handle = dlopen("libcurl.so", RTLD_NOW);
    if (!handle) {
      alert("HTTP: libcurl not found on this machine, http request ignored.");
      return;
    }

    _curl_global_init = (curl_global_init_t)dlsym(handle, "curl_global_init");
    _curl_slist_append =
        (curl_slist_append_t)dlsym(handle, "curl_slist_append");
    _curl_slist_free_all =
        (curl_slist_free_all_t)dlsym(handle, "curl_slist_free_all");

    _curl_easy_init   = (curl_easy_init_t)dlsym(handle, "curl_easy_init");
    _curl_easy_setopt = (curl_easy_setopt_t)dlsym(handle, "curl_easy_setopt");
    _curl_easy_getinfo =
        (curl_easy_getinfo_t)dlsym(handle, "curl_easy_getinfo");
    _curl_easy_perform =
        (curl_easy_perform_t)dlsym(handle, "curl_easy_perform");
    _curl_easy_cleanup =
        (curl_easy_cleanup_t)dlsym(handle, "curl_easy_cleanup");

    if (_curl_global_init && _curl_slist_append && _curl_slist_free_all &&
        _curl_easy_init && _curl_easy_setopt && _curl_easy_getinfo &&
        _curl_easy_perform && _curl_easy_cleanup)
      inet = new curl_inet_client();
jsprog commented 3 years ago

I think that I shouldn't said 'Not sure if you typed this correctly?' for a simple reason, because I executed some tests after renaming the symbolic links and could confirm that sciter.js couldn't reach them if they were both removed. Sorry about this.

Anyway, I'll try to share after running some other tests, but don't expect it too soon like the previous posts. We're having a huge time difference.