stream.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. const { getStream, getSecureStream } = getStreamFuncs()
  2. module.exports = {
  3. /**
  4. * Get a socket stream compatible with the current runtime environment.
  5. * @returns {Duplex}
  6. */
  7. getStream,
  8. /**
  9. * Get a TLS secured socket, compatible with the current environment,
  10. * using the socket and other settings given in `options`.
  11. * @returns {Duplex}
  12. */
  13. getSecureStream,
  14. }
  15. /**
  16. * The stream functions that work in Node.js
  17. */
  18. function getNodejsStreamFuncs() {
  19. function getStream(ssl) {
  20. const net = require('net')
  21. return new net.Socket()
  22. }
  23. function getSecureStream(options) {
  24. var tls = require('tls')
  25. return tls.connect(options)
  26. }
  27. return {
  28. getStream,
  29. getSecureStream,
  30. }
  31. }
  32. /**
  33. * The stream functions that work in Cloudflare Workers
  34. */
  35. function getCloudflareStreamFuncs() {
  36. function getStream(ssl) {
  37. const { CloudflareSocket } = require('pg-cloudflare')
  38. return new CloudflareSocket(ssl)
  39. }
  40. function getSecureStream(options) {
  41. options.socket.startTls(options)
  42. return options.socket
  43. }
  44. return {
  45. getStream,
  46. getSecureStream,
  47. }
  48. }
  49. /**
  50. * Are we running in a Cloudflare Worker?
  51. *
  52. * @returns true if the code is currently running inside a Cloudflare Worker.
  53. */
  54. function isCloudflareRuntime() {
  55. // Since 2022-03-21 the `global_navigator` compatibility flag is on for Cloudflare Workers
  56. // which means that `navigator.userAgent` will be defined.
  57. if (typeof navigator === 'object' && navigator !== null && typeof navigator.userAgent === 'string') {
  58. return navigator.userAgent === 'Cloudflare-Workers'
  59. }
  60. // In case `navigator` or `navigator.userAgent` is not defined then try a more sneaky approach
  61. if (typeof Response === 'function') {
  62. const resp = new Response(null, { cf: { thing: true } })
  63. if (typeof resp.cf === 'object' && resp.cf !== null && resp.cf.thing) {
  64. return true
  65. }
  66. }
  67. return false
  68. }
  69. function getStreamFuncs() {
  70. if (isCloudflareRuntime()) {
  71. return getCloudflareStreamFuncs()
  72. }
  73. return getNodejsStreamFuncs()
  74. }