Skip to content

Commit 74714b0

Browse files
refactor: tighten up cloudflare detection
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.
1 parent a24a24d commit 74714b0

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

packages/pg/lib/stream.js

+37-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
let isCloudflareRuntime
2+
13
/**
24
* Get a socket stream compatible with the current runtime environment.
35
* @returns {Duplex}
46
*/
57
module.exports.getStream = function getStream(ssl) {
6-
const net = require('net')
7-
if (typeof net.Socket === 'function') {
8-
return new net.Socket()
9-
} else {
8+
if (isCloudflareRuntime === undefined) {
9+
isCloudflareRuntime = computeIsCloudflareRuntime()
10+
}
11+
if (isCloudflareRuntime) {
1012
const { CloudflareSocket } = require('pg-cloudflare')
1113
return new CloudflareSocket(ssl)
14+
} else {
15+
const net = require('net')
16+
return new net.Socket()
1217
}
1318
}
1419

@@ -18,11 +23,35 @@ module.exports.getStream = function getStream(ssl) {
1823
* @returns {Duplex}
1924
*/
2025
module.exports.getSecureStream = function getSecureStream(options) {
21-
var tls = require('tls')
22-
if (tls.connect) {
23-
return tls.connect(options)
24-
} else {
26+
if (isCloudflareRuntime === undefined) {
27+
isCloudflareRuntime = computeIsCloudflareRuntime()
28+
}
29+
if (isCloudflareRuntime) {
2530
options.socket.startTls(options)
2631
return options.socket
32+
} else {
33+
var tls = require('tls')
34+
return tls.connect(options)
35+
}
36+
}
37+
38+
/**
39+
* Are we running in a Cloudflare Worker?
40+
*
41+
* @returns true if the code is currently running inside a Cloudflare Worker.
42+
*/
43+
function computeIsCloudflareRuntime() {
44+
// Since 2022-03-21 the `global_navigator` compatibility flag is on for Cloudflare Workers
45+
// which means that `navigator.userAgent` will be defined.
46+
if (typeof navigator === 'object' && navigator !== null && typeof navigator.userAgent === 'string') {
47+
return navigator.userAgent === 'Cloudflare-Workers'
48+
}
49+
// In case `navigator` or `navigator.userAgent` is not defined then try a more sneaky approach
50+
if (typeof Response === 'function') {
51+
const resp = new Response(null, { cf: { thing: true } })
52+
if (typeof resp.cf === 'object' && resp.cf !== null && resp.cf.thing) {
53+
return true
54+
}
2755
}
56+
return false
2857
}

0 commit comments

Comments
 (0)