Skip to content

Commit

Permalink
refactor: tighten up cloudflare detection
Browse files Browse the repository at this point in the history
The previous approach to detecting whether to use Cloudflare's sockets was to check for missing polyfills.
But as we improve the polyfills that Wrangler can provide these checks are no longer valid.

Now we just try to use the Cloudflare API first and fallback to Node.js if those are not available.
  • Loading branch information
petebacondarwin committed Jun 10, 2024
1 parent a24a24d commit 74714b0
Showing 1 changed file with 37 additions and 8 deletions.
45 changes: 37 additions & 8 deletions packages/pg/lib/stream.js
Original file line number Diff line number Diff line change
@@ -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()
}
}

Expand All @@ -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
}

0 comments on commit 74714b0

Please sign in to comment.