diff --git a/packages/pg/lib/stream.js b/packages/pg/lib/stream.js index 67b1b3c81..7bde856fc 100644 --- a/packages/pg/lib/stream.js +++ b/packages/pg/lib/stream.js @@ -1,14 +1,19 @@ +let isCloudflareRuntime + /** * Get a socket stream compatible with the current runtime environment. * @returns {Duplex} */ module.exports.getStream = function getStream(ssl) { - const net = require('net') - if (typeof net.Socket === 'function') { - return new net.Socket() - } else { + if (isCloudflareRuntime === undefined) { + isCloudflareRuntime = computeIsCloudflareRuntime() + } + if (isCloudflareRuntime) { const { CloudflareSocket } = require('pg-cloudflare') return new CloudflareSocket(ssl) + } else { + const net = require('net') + return new net.Socket() } } @@ -18,11 +23,35 @@ module.exports.getStream = function getStream(ssl) { * @returns {Duplex} */ module.exports.getSecureStream = function getSecureStream(options) { - var tls = require('tls') - if (tls.connect) { - return tls.connect(options) - } else { + if (isCloudflareRuntime === undefined) { + isCloudflareRuntime = computeIsCloudflareRuntime() + } + if (isCloudflareRuntime) { options.socket.startTls(options) return options.socket + } else { + var tls = require('tls') + return tls.connect(options) + } +} + +/** + * Are we running in a Cloudflare Worker? + * + * @returns true if the code is currently running inside a Cloudflare Worker. + */ +function computeIsCloudflareRuntime() { + // Since 2022-03-21 the `global_navigator` compatibility flag is on for Cloudflare Workers + // which means that `navigator.userAgent` will be defined. + if (typeof navigator === 'object' && navigator !== null && typeof navigator.userAgent === 'string') { + return navigator.userAgent === 'Cloudflare-Workers' + } + // In case `navigator` or `navigator.userAgent` is not defined then try a more sneaky approach + if (typeof Response === 'function') { + const resp = new Response(null, { cf: { thing: true } }) + if (typeof resp.cf === 'object' && resp.cf !== null && resp.cf.thing) { + return true + } } + return false }