310d35e69c
This commit includes 2 things: 1. Sometimes (seemingly due to client caching), performance entries aren't available, even for the currently executing script. This waits until the first retrieval of 'CONSUL_HTTP_PROTOCOL' before using the performance entries to decide this. This means that the entries aren't inspected until ember has initialized, which means that the entries are always available. 2. getCurrentResource/getResourceFor could potentially return undefined if the correct entry could not be found. This adds a default {} return value if the resource cannot be found. This means that if for whatever reason the correct resource cannot be found at least we don't fail with an error and just drop back to HTTP/1 functionality.
112 lines
3.8 KiB
JavaScript
112 lines
3.8 KiB
JavaScript
export default function(config = {}, win = window, doc = document) {
|
|
const dev = function() {
|
|
return doc.cookie
|
|
.split(';')
|
|
.filter(item => item !== '')
|
|
.map(item => item.trim().split('='));
|
|
};
|
|
const user = function(str) {
|
|
const item = win.localStorage.getItem(str);
|
|
return item === null ? undefined : item;
|
|
};
|
|
const getResourceFor = function(src) {
|
|
try {
|
|
return (
|
|
win.performance.getEntriesByType('resource').find(item => {
|
|
return item.initiatorType === 'script' && src === item.name;
|
|
}) || {}
|
|
);
|
|
} catch (e) {
|
|
return {};
|
|
}
|
|
};
|
|
const scripts = doc.getElementsByTagName('script');
|
|
const currentSrc = scripts[scripts.length - 1].src;
|
|
let resource;
|
|
|
|
// TODO: Look to see if we can pull in HTTP headers here
|
|
// so we can let things be controlled via HTTP proxies, for example
|
|
// turning off blocking queries if its a busy cluster etc
|
|
const operator = function(str, env) {
|
|
let protocol;
|
|
switch (str) {
|
|
case 'CONSUL_HTTP_PROTOCOL':
|
|
if (typeof resource === 'undefined') {
|
|
// resource needs to be retrieved lazily as entries aren't guaranteed
|
|
// to be available at script execution time (caching seems to affect this)
|
|
// waiting until we retrieve this value lazily at runtime means that
|
|
// the entries are always available as these values are only retrieved
|
|
// after initialization
|
|
// current is based on the assumption that whereever this script is it's
|
|
// likely to be the same as the xmlhttprequests
|
|
resource = getResourceFor(currentSrc);
|
|
}
|
|
return resource.nextHopProtocol || 'http/1.1';
|
|
case 'CONSUL_HTTP_MAX_CONNECTIONS':
|
|
protocol = env('CONSUL_HTTP_PROTOCOL');
|
|
// http/2, http2+QUIC/39 and SPDY don't have connection limits
|
|
switch (true) {
|
|
case protocol.indexOf('h2') === 0:
|
|
case protocol.indexOf('hq') === 0:
|
|
case protocol.indexOf('spdy') === 0:
|
|
// TODO: Change this to return -1 so we try to consistently
|
|
// return a value from env vars
|
|
return;
|
|
default:
|
|
// generally 6 are available
|
|
// reserve 1 for traffic that we can't manage
|
|
return 5;
|
|
}
|
|
}
|
|
};
|
|
const ui = function(key) {
|
|
let $;
|
|
switch (config.environment) {
|
|
case 'development':
|
|
case 'staging':
|
|
case 'coverage':
|
|
case 'test':
|
|
$ = dev().reduce(function(prev, [key, value]) {
|
|
switch (key) {
|
|
case 'CONSUL_ACLS_ENABLE':
|
|
prev['CONSUL_ACLS_ENABLED'] = !!JSON.parse(String(value).toLowerCase());
|
|
break;
|
|
case 'CONSUL_NSPACES_ENABLE':
|
|
prev['CONSUL_NSPACES_ENABLED'] = !!JSON.parse(String(value).toLowerCase());
|
|
break;
|
|
default:
|
|
prev[key] = value;
|
|
}
|
|
return prev;
|
|
}, {});
|
|
if (typeof $[key] !== 'undefined') {
|
|
return $[key];
|
|
}
|
|
break;
|
|
}
|
|
return config[key];
|
|
};
|
|
return function env(str) {
|
|
switch (str) {
|
|
// All user providable values should start with CONSUL_UI
|
|
// We allow the user to set these ones via localStorage
|
|
// user value is preferred.
|
|
case 'CONSUL_UI_DISABLE_REALTIME':
|
|
case 'CONSUL_UI_DISABLE_ANCHOR_SELECTION':
|
|
// these are booleans cast things out
|
|
return !!JSON.parse(String(user(str) || 0).toLowerCase()) || ui(str);
|
|
case 'CONSUL_UI_REALTIME_RUNNER':
|
|
// these are strings
|
|
return user(str) || ui(str);
|
|
|
|
case 'CONSUL_HTTP_PROTOCOL':
|
|
case 'CONSUL_HTTP_MAX_CONNECTIONS':
|
|
// We allow the operator to set these ones via various methods
|
|
// although UI developer config is preferred
|
|
return ui(str) || operator(str, env);
|
|
default:
|
|
return ui(str);
|
|
}
|
|
};
|
|
}
|