Skip to content

Commit f7e484e

Browse files
refactor: tighten up cloudflare detection (#3170)
* 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. * fixup! refactor: tighten up cloudflare detection
1 parent 3e4d545 commit f7e484e

File tree

1 file changed

+69
-16
lines changed

1 file changed

+69
-16
lines changed

packages/pg/lib/stream.js

+69-16
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,81 @@
1+
const { getStream, getSecureStream } = getStreamFuncs()
2+
3+
module.exports = {
4+
/**
5+
* Get a socket stream compatible with the current runtime environment.
6+
* @returns {Duplex}
7+
*/
8+
getStream,
9+
/**
10+
* Get a TLS secured socket, compatible with the current environment,
11+
* using the socket and other settings given in `options`.
12+
* @returns {Duplex}
13+
*/
14+
getSecureStream,
15+
}
16+
117
/**
2-
* Get a socket stream compatible with the current runtime environment.
3-
* @returns {Duplex}
18+
* The stream functions that work in Node.js
419
*/
5-
module.exports.getStream = function getStream(ssl) {
6-
const net = require('net')
7-
if (typeof net.Socket === 'function') {
20+
function getNodejsStreamFuncs() {
21+
function getStream(ssl) {
22+
const net = require('net')
823
return new net.Socket()
9-
} else {
10-
const { CloudflareSocket } = require('pg-cloudflare')
11-
return new CloudflareSocket(ssl)
24+
}
25+
26+
function getSecureStream(options) {
27+
var tls = require('tls')
28+
return tls.connect(options)
29+
}
30+
return {
31+
getStream,
32+
getSecureStream,
1233
}
1334
}
1435

1536
/**
16-
* Get a TLS secured socket, compatible with the current environment,
17-
* using the socket and other settings given in `options`.
18-
* @returns {Duplex}
37+
* The stream functions that work in Cloudflare Workers
1938
*/
20-
module.exports.getSecureStream = function getSecureStream(options) {
21-
var tls = require('tls')
22-
if (tls.connect) {
23-
return tls.connect(options)
24-
} else {
39+
function getCloudflareStreamFuncs() {
40+
function getStream(ssl) {
41+
const { CloudflareSocket } = require('pg-cloudflare')
42+
return new CloudflareSocket(ssl)
43+
}
44+
45+
function getSecureStream(options) {
2546
options.socket.startTls(options)
2647
return options.socket
2748
}
49+
return {
50+
getStream,
51+
getSecureStream,
52+
}
53+
}
54+
55+
/**
56+
* Are we running in a Cloudflare Worker?
57+
*
58+
* @returns true if the code is currently running inside a Cloudflare Worker.
59+
*/
60+
function isCloudflareRuntime() {
61+
// Since 2022-03-21 the `global_navigator` compatibility flag is on for Cloudflare Workers
62+
// which means that `navigator.userAgent` will be defined.
63+
if (typeof navigator === 'object' && navigator !== null && typeof navigator.userAgent === 'string') {
64+
return navigator.userAgent === 'Cloudflare-Workers'
65+
}
66+
// In case `navigator` or `navigator.userAgent` is not defined then try a more sneaky approach
67+
if (typeof Response === 'function') {
68+
const resp = new Response(null, { cf: { thing: true } })
69+
if (typeof resp.cf === 'object' && resp.cf !== null && resp.cf.thing) {
70+
return true
71+
}
72+
}
73+
return false
74+
}
75+
76+
function getStreamFuncs() {
77+
if (isCloudflareRuntime()) {
78+
return getCloudflareStreamFuncs()
79+
}
80+
return getNodejsStreamFuncs()
2881
}

0 commit comments

Comments
 (0)