ipc-protocol.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. ;(function () {
  5. const processIpcMessage = __RAW_process_ipc_message_fn__
  6. const osName = __TEMPLATE_os_name__
  7. const fetchChannelDataCommand = __TEMPLATE_fetch_channel_data_command__
  8. const linuxIpcProtocolEnabled = __TEMPLATE_linux_ipc_protocol_enabled__
  9. let customProtocolIpcFailed = false
  10. // on Linux we only use the custom-protocol-based IPC if the the linux-ipc-protocol Cargo feature is enabled
  11. // on Android we never use it because Android does not have support to reading the request body
  12. const canUseCustomProtocol =
  13. osName === 'linux' ? linuxIpcProtocolEnabled : osName !== 'android'
  14. function sendIpcMessage(message) {
  15. const { cmd, callback, error, payload, options } = message
  16. if (
  17. !customProtocolIpcFailed &&
  18. (canUseCustomProtocol || cmd === fetchChannelDataCommand)
  19. ) {
  20. const { contentType, data } = processIpcMessage(payload)
  21. fetch(window.__TAURI_INTERNALS__.convertFileSrc(cmd, 'ipc'), {
  22. method: 'POST',
  23. body: data,
  24. headers: {
  25. 'Content-Type': contentType,
  26. 'Tauri-Callback': callback,
  27. 'Tauri-Error': error,
  28. ...options?.headers
  29. }
  30. })
  31. .then((response) => {
  32. const cb = response.ok ? callback : error
  33. // we need to split here because on Android the content-type gets duplicated
  34. switch ((response.headers.get('content-type') || '').split(',')[0]) {
  35. case 'application/json':
  36. return response.json().then((r) => [cb, r])
  37. case 'text/plain':
  38. return response.text().then((r) => [cb, r])
  39. default:
  40. return response.arrayBuffer().then((r) => [cb, r])
  41. }
  42. })
  43. .then(([cb, data]) => {
  44. if (window[`_${cb}`]) {
  45. window[`_${cb}`](data)
  46. } else {
  47. console.warn(
  48. `[TAURI] Couldn't find callback id {cb} in window. This might happen when the app is reloaded while Rust is running an asynchronous operation.`
  49. )
  50. }
  51. })
  52. .catch(() => {
  53. // failed to use the custom protocol IPC (either the webview blocked a custom protocol or it was a CSP error)
  54. // so we need to fallback to the postMessage interface
  55. customProtocolIpcFailed = true
  56. sendIpcMessage(message)
  57. })
  58. } else {
  59. // otherwise use the postMessage interface
  60. const { data } = processIpcMessage({
  61. cmd,
  62. callback,
  63. error,
  64. options,
  65. payload
  66. })
  67. window.ipc.postMessage(data)
  68. }
  69. }
  70. Object.defineProperty(window.__TAURI_INTERNALS__, 'postMessage', {
  71. value: sendIpcMessage
  72. })
  73. })()