matrix-org / olm

An implementation of the Double Ratchet cryptographic ratchet in C++/C
https://gitlab.matrix.org/matrix-org/olm
63 stars 9 forks source link

OLM.init() fails in react application #65

Closed Crash22191 closed 2 years ago

Crash22191 commented 3 years ago

Describe the bug

wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

To Reproduce

  1. Create react application
  2. Set dependencies of matrix-js-sdk and Olm in package.json
    "matrix-js-sdk": "^12.3.1",
    "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.6.tgz",
  3. Create a js class with OLM and SDK imports
  4. Set global.Olm = Olm
  5. Create Matrix Client
  6. Callclient.initCrypto() Fail on global.Olm.init()

macOs: Safari, Chrome, FireFox Tried several versions of OLM, all of them fail.

uhoreg commented 3 years ago

That error generally means that it's getting the wrong contents for the .wasm file, probably a 404 response. The error shows that the first four bytes of the file are 3c 21 44 4f which is <!DO, which indicates that it's probably getting an HTML file. Check the browser to see where it's loading the .wasm file from, and make sure that the .wasm file is actually accessible from that location.

Crash22191 commented 3 years ago

@uhoreg I do everything according to matrix/olm documentation, wasm file is in the same folder as olm.js so it is accessible. Have you tried replicating the issue ?

uhoreg commented 3 years ago

It does work in other webapps like Element and Hydrogen, so we know it works. Having the wasm file in the same directory as the js file may not be the right place. As I said, check the browser's developer tools to see where it's trying to load the wasm file from.

Crash22191 commented 3 years ago

I've added some logging to the codebase (//new log) and looks like it's fetching a right file and it's bytes but failing anyway :

      function d(f) {
                      return Ia().then(function(k) {
                        //new log 
                        console.log("wasm binary ")
                        console.log(k)
                          return WebAssembly.instantiate(k,
                              e)
                      }).then(function(k) {
                          return k
                      }).then(f, function(k) {
                          ma("failed to asynchronously prepare wasm: " + k);
                          r(k)
                      })
                  }
              function Ia() {
                  if (!na && (ha || ia)) {
                      if ("function" === typeof fetch && !D.startsWith("file://")) return fetch(D, {
                          credentials: "same-origin"
                      }).then(function(b) {
                          if (!b.ok) throw "failed to load wasm binary file at '" + D + "'";
                          //new log
                          if(b.ok) console.log("Loaded file at " + D)
                          return b.arrayBuffer()
                      }).catch(function() {
                          return Ha()
                      });
                      if (ka) return new Promise(function(b, c) {
                          ka(D, function(d) {
                              b(new Uint8Array(d))
                          }, c)
                      })
                  }
                  return Promise.resolve().then(function() {
                      return Ha()
                  })
              }

Console:

Loaded binary at http://localhost:3000/client/static/js/olm.wasm
wasm binary 
ArrayBuffer(2218) 
failed to asynchronously prepare wasm: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
initCrypto Error
TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'
uhoreg commented 3 years ago

ArrayBuffer(2218)

That doesn't look right. The olm.wasm on my machine is 158011 bytes. 2218 bytes is way too small.

Have you checked http://localhost:3000/client/static/js/olm.wasm to see what's actually being served?

Crash22191 commented 3 years ago

I think I found a workaround tho, I moved wasm file to /public and instead of D = a.locateFile ? a.locateFile(Ga, m) : m + Ga I did D = (process.env.PUBLIC_URL + "/olm.wasm") Sounds like it's a react specific problem tho

uhoreg commented 2 years ago

Added a note in the readme about how to tell olm where the wasm file is: https://gitlab.matrix.org/matrix-org/olm/-/commit/06b723db6e7b37545145487bf244e41500455c97