Comparing 2 attributes using the function "some" - javascript

var e = require("./myApp.js");
var myServer = e.CreateServer(1337);
myServer.Register("/", "GET", function (req, res) { res.end("J") });
myServer.Register("/", "GET", function (req, res) { res.end("Ja") });
myServer.Start();
This is my "Wrapper":
module.exports = (function () {
function _createServer(port) {
var routingTable = [];
var port = port;
var server = require('http').createServer();
function _start() {
server.listen(port);
console.log("Server was started");
};
function RegisterRecord(url, method, fnc) {
this.url = url;
this.method = method;
this.fnc = fnc;
};
function _register(newUrl, newMethod, newFnc) {
if (_checkInput(newUrl, newMethod))
console.log("Register failed! Record with same URL and Method already exist");
else {
routingTable.push(new RegisterRecord(newUrl, newMethod, newFnc));
console.log("Register success!");
}
};
function _checkInput(newUrl, newMethod) {
return routingTable.some(function fnc(record) { record.url == newUrl && record.method == newMethod });
};
return {
Start: _start,
Register: _register,
ShutDown: _shutDown
};
};
return { CreateServer: _createServer };
})();
So the most important functions are "_register" and "checkInput".
My aim is that the same URL and Method are only allowed on time in the array routingTable. So when I execute the programm, the Command Promp prints two times Register success. But "/" and "GET" should only be allowed one time.
How can I compare the URL and method so that they can be unique?
PS: The "Wrapper" is in the JS File "./MyApp.js"

You need filter:
function _checkInput(newUrl, newMethod) {
return routingTable
.filter( function(el) {
return el.url === newUrl && el.method === newMethod;
})
.length > 0;
};
Upd. Of course, you can use the some - you just forgot to return a value from it:
function _checkInput(newUrl, newMethod) {
return routingTable
.some( function(el) {
// Need return
return el.url === newUrl && el.method === newMethod;
})
};

Related

Unhandled error Error: Data cannot be encoded in JSON error at firebase serverless functions

I'm trying to deploy an api for my application. Using these codes raises Unhandled error "Error: Data cannot be encoded in JSON.
const functions = require("firebase-functions");
const axios = require("axios");
exports.getDatas = functions.https.onCall(async (d)=>{
functions.logger.log(d["name"]);
cname = d["name"];
ts1=d["ts1"];
ts2=d["ts2"];
const data = await axios.get(
"https://api.coingecko.com/api/v3/coins/" +
cname +
"/market_chart/range?vs_currency=usd&from=" +
ts1 +
"&to=" +
ts2,
);
functions.logger.log(data);
return {data: data};
});
The error log is
Unhandled error Error: Data cannot be encoded in JSON: function httpAdapter(config) {
return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
var onCanceled;
function done() {
if (config.cancelToken) {
config.cancelToken.unsubscribe(onCanceled);
}
if (config.signal) {
config.signal.removeEventListener('abort', onCanceled);
}
}
var resolve = function resolve(value) {
done();
resolvePromise(value);
};
var rejected = false;
var reject = function reject(value) {
done();
rejected = true;
rejectPromise(value);
};
var data = config.data;
var headers = config.headers;
var headerNames = {};
Object.keys(headers).forEach(function storeLowerName(name) {
headerNames[name.toLowerCase()] = name;
});
// Set User-Agent (required by some servers)
// See https://github.com/axios/axios/issues/69
if ('user-agent' in headerNames) {
// User-Agent is specified; handle case where no UA header is desired
if (!headers[headerNames['user-agent']]) {
delete headers[headerNames['user-agent']];
}
// Otherwise, use specified value
} else {
// Only set header if it hasn't been set in config
headers['User-Agent'] = 'axios/' + VERSION;
}
if (data && !utils.isStream(data)) {
if (Buffer.isBuffer(data)) {
// Nothing to do...
} else if (utils.isArrayBuffer(data)) {
data = Buffer.from(new Uint8Array(data));
} else if (utils.isString(data)) {
data = Buffer.from(data, 'utf-8');
} else {
return reject(createError(
'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',
config
));
}
if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
return reject(createError('Request body larger than maxBodyLength limit', config));
}
// Add Content-Length header if data exists
if (!headerNames['content-length']) {
headers['Content-Length'] = data.length;
}
}
// HTTP basic authentication
var auth = undefined;
if (config.auth) {
var username = config.auth.username || '';
var password = config.auth.password || '';
auth = username + ':' + password;
}
// Parse url
var fullPath = buildFullPath(config.baseURL, config.url);
var parsed = url.parse(fullPath);
var protocol = parsed.protocol || 'http:';
if (!auth && parsed.auth) {
var urlAuth = parsed.auth.split(':');
var urlUsername = urlAuth[0] || '';
var urlPassword = urlAuth[1] || '';
auth = urlUsername + ':' + urlPassword;
}
if (auth && headerNames.authorization) {
delete headers[headerNames.authorization];
}
var isHttpsRequest = isHttps.test(protocol);
var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
var options = {
path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''),
method: config.method.toUpperCase(),
headers: headers,
agent: agent,
agents: { http: config.httpAgent, https: config.httpsAgent },
auth: auth
};
if (config.socketPath) {
options.socketPath = config.socketPath;
} else {
options.hostname = parsed.hostname;
options.port = parsed.port;
}
var proxy = config.proxy;
if (!proxy && proxy !== false) {
var proxyEnv = protocol.slice(0, -1) + '_proxy';
var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()];
if (proxyUrl) {
var parsedProxyUrl = url.parse(proxyUrl);
var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY;
var shouldProxy = true;
if (noProxyEnv) {
var noProxy = noProxyEnv.split(',').map(function trim(s) {
return s.trim();
});
shouldProxy = !noProxy.some(function proxyMatch(proxyElement) {
if (!proxyElement) {
return false;
}
if (proxyElement === '*') {
return true;
}
if (proxyElement[0] === '.' &&
parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) {
return true;
}
return parsed.hostname === proxyElement;
});
}
if (shouldProxy) {
proxy = {
host: parsedProxyUrl.hostname,
port: parsedProxyUrl.port,
protocol: parsedProxyUrl.protocol
};
if (parsedProxyUrl.auth) {
var proxyUrlAuth = parsedProxyUrl.auth.split(':');
proxy.auth = {
username: proxyUrlAuth[0],
password: proxyUrlAuth[1]
};
}
}
}
}
if (proxy) {
options.headers.host = parsed.hostname + (parsed.port ? ':' + parsed.port : '');
setProxy(options, proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
}
var transport;
var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true);
if (config.transport) {
transport = config.transport;
} else if (config.maxRedirects === 0) {
transport = isHttpsProxy ? https : http;
} else {
if (config.maxRedirects) {
options.maxRedirects = config.maxRedirects;
}
transport = isHttpsProxy ? httpsFollow : httpFollow;
}
if (config.maxBodyLength > -1) {
options.maxBodyLength = config.maxBodyLength;
}
if (config.insecureHTTPParser) {
options.insecureHTTPParser = config.insecureHTTPParser;
}
// Create the request
var req = transport.request(options, function handleResponse(res) {
if (req.aborted) return;
// uncompress the response body transparently if required
var stream = res;
// return the last request in case of redirects
var lastRequest = res.req || req;
// if no content, is HEAD request or decompress disabled we should not decompress
if (res.statusCode !== 204 && lastRequest.method !== 'HEAD' && config.decompress !== false) {
switch (res.headers['content-encoding']) {
/*eslint default-case:0*/
case 'gzip':
case 'compress':
case 'deflate':
// add the unzipper to the body stream processing pipeline
stream = stream.pipe(zlib.createUnzip());
// remove the content-encoding in order to not confuse downstream operations
delete res.headers['content-encoding'];
break;
}
}
var response = {
status: res.statusCode,
statusText: res.statusMessage,
headers: res.headers,
config: config,
request: lastRequest
};
if (config.responseType === 'stream') {
response.data = stream;
settle(resolve, reject, response);
} else {
var responseBuffer = [];
var totalResponseBytes = 0;
stream.on('data', function handleStreamData(chunk) {
responseBuffer.push(chunk);
totalResponseBytes += chunk.length;
// make sure the content length is not over the maxContentLength if specified
if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
// stream.destoy() emit aborted event before calling reject() on Node.js v16
rejected = true;
stream.destroy();
reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
config, null, lastRequest));
}
});
stream.on('aborted', function handlerStreamAborted() {
if (rejected) {
return;
}
stream.destroy();
reject(createError('error request aborted', config, 'ERR_REQUEST_ABORTED', lastRequest));
});
stream.on('error', function handleStreamError(err) {
if (req.aborted) return;
reject(enhanceError(err, config, null, lastRequest));
});
stream.on('end', function handleStreamEnd() {
try {
var responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);
if (config.responseType !== 'arraybuffer') {
responseData = responseData.toString(config.responseEncoding);
if (!config.responseEncoding || config.responseEncoding === 'utf8') {
responseData = utils.stripBOM(responseData);
}
}
response.data = responseData;
} catch (err) {
reject(enhanceError(err, config, err.code, response.request, response));
}
settle(resolve, reject, response);
});
}
});
// Handle errors
req.on('error', function handleRequestError(err) {
if (req.aborted && err.code !== 'ERR_FR_TOO_MANY_REDIRECTS') return;
reject(enhanceError(err, config, null, req));
});
// set tcp keep alive to prevent drop connection by peer
req.on('socket', function handleRequestSocket(socket) {
// default interval of sending ack packet is 1 minute
socket.setKeepAlive(true, 1000 * 60);
});
// Handle request timeout
if (config.timeout) {
// This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
var timeout = parseInt(config.timeout, 10);
if (isNaN(timeout)) {
reject(createError(
'error trying to parse `config.timeout` to int',
config,
'ERR_PARSE_TIMEOUT',
req
));
return;
}
// Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.
// And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.
// At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up.
// And then these socket which be hang up will devoring CPU little by little.
// ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
req.setTimeout(timeout, function handleRequestTimeout() {
req.abort();
var transitional = config.transitional || defaults.transitional;
reject(createError(
'timeout of ' + timeout + 'ms exceeded',
config,
transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
req
));
});
}
if (config.cancelToken || config.signal) {
// Handle cancellation
// eslint-disable-next-line func-names
onCanceled = function(cancel) {
if (req.aborted) return;
req.abort();
reject(!cancel || (cancel && cancel.type) ? new Cancel('canceled') : cancel);
};
config.cancelToken && config.cancelToken.subscribe(onCanceled);
if (config.signal) {
config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);
}
}
// Send the request
if (utils.isStream(data)) {
data.on('error', function handleStreamError(err) {
reject(enhanceError(err, config, null, req));
}).pipe(req);
} else {
req.end(data);
}
});
}
at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:162:11)
at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:156:22)
at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:156:22)
at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:156:22)
at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:334:22
at processTicksAndRejections (internal/process/task_queues.js:97:5)
First logger logs the parameter i gave correctly and the logger that logs data is in this format:
...["api.coingecko.com:443::::::::::::::::::"]},"keepAliveMsecs":1000,"maxFreeSockets":256,"scheduling":"fifo","keepAlive":false,"maxSockets":null},"_removedConnection":false,"writable":true},"status":200,"data":{"prices":[[1615345414698,37.27069164629981],[1615349310788,36.95627388647297],[1615352802175,37.48630338203377],[1615356202751,37.46442850999597],[1615360079361,37.642735963063906],[1615363905145,38.29435586902702],[1615367492353,38.313292928237594],[1615370461299,38.75503558097479],[1615374138056,38.24406575020552],[1615377815960,38.237026584388175],[1615381321332,38.93964664468625],[1615384813000,39.262646397955635],[1615388739874,39.15882057568881],[1615392094129,38.94488140309047],[1615395966875,38.79820936257378],[1615399312625,38.51637055616189],[1615403055037,38.59237008394828],[1615406529740,38.44087305010874],[1615410281814,37.71855645797291],[1615414278815,38.374824600586976],[1615417716420,38.4538669693684],[1615421045728,37.62772478442999],[1615425672990,36.8826465121472],[1615429587089,37.41958697414903],[1615432278494,37.34865694722488],[1615435254265,37.16289143388951],[1615439122292,37.14731463575248],[1615442523394,36.801517989796814],[1615446290102,37.02248224990424],[1615450361470,36.164787531097126],[1615453299572,36.46191265162147],[1615457172317,36.174755169666334],[1615460886498,37.05778010952229],[1615464298322,37.336909500902365],[1615469586325,37.56497212211488],[1615472126260,37.83046394206218],[1615474882979,37.252561357731096],[1615478498201,36.56190097084664],[1615482336185,36.83824760787625],[1615485957910,36.89351702770813],[1615489642151,37.589229946501746],[1615493390438,37.33184737771527],[1615496666244,37.29234576242379],[1615500577712,37.284260441548426],[1616866645601,1137195941.0307472],[1616870299925,1089416195.9864128],[1616873841648,1074341877.495249],[1616877368137,1061555457.3375872],[1616880970910,1077775411.1216433],[1616884693948,1064594490.6022671],[1616887998472,1087481667.611567],[1616891397951,1068140794.5197278],[1616894759953,1078753362.1719048],[1616898371565,1053546315.1245787],[1616902002474,1052498816.7223371],[1616905584364,1026915395.5541993],[1616909101481,1022271206.3215427],[1616912730390,997185793.1210617],[1616916434482,972130048.6316774],[1616919928611,988711196.2721183],[1616923534317,987299160.6191593],[1616926264719,975360472.6011684],[1616930074136,958327264.7346151],[1616933292776,935085970.8922312],[1616936940791,896217168.3654604],[1616940936847,878876312.6707534],[1616944090304,890504985.5476977],[1616948321869,896715385.5657766],[1616952007508,870767231.0865391],[1616955544207,880601758.4610194],[1616958381375,896794852.1077055],[1616962022167,929362788.5783823],[1616966479654,927502494.4691795],[1616969648773,880385481.5284289],[1616973545649,862329007.9935848],[1616977463095,840138544.6360805],[1616980359587,849727926.595521],[1616984356096,820616225.3306137],[1616987602367,898085663.0760688],[1616990444958,890215727.4112909],[1616995470635,914823340.6343507],[1616999032159,890922230.685704],[1617002651977,937214914.0703756],[1617005329558,976030203.3879734],[1617009370471,1061898884.4388478],[1617012348377,1111994349.2592206],[1617015705482,1175310227.1595278],[1617019895549,1217044915.3900926],[1617022941451,1204239369.9336267],[1617027118715,1225123359.1178432],[1617031210170,1191418570.9198012],[1617033728601,1257085051.9742537],[1617037882992,1261291734.3667347],[1617041858553,1265805909.4506621],[1617044547418,1261869965.5784621],[1617049418534,1225924891.220988],[1617052450394,1200646247.466799],[1617055896172,1209247034.0807025],[1617059684123,1249662106.3996315],[1617062561979,837849935.5380555],[1617066155823,1261094295.2039979],[1617070572708,1244044711.3556864],[1617074210159,1178503497.252399],[1617077106612,1184744920.254339],[1617080571662,1219164970.9205332],[1617084836477,1174744890.1399443],[1617087739776,1236332180.5454476],[1617092763739,1121685108.4046226],[1617096303391,1074005978.1362224],[1617100013739,1075898891.906641],[1617102136947,1041120230.0169744],[1617106411165,1021062028.7444541],[1617110588848,1004207600.6385714],[1617114148509,983098685.435342],[1617117449987,983878432.6976557],[1617120868725,943893192.0239582],[1617123806180,948379973.8680001],[1617128347360,948328240.0510467],[1617131244094,923477307.6495335],[1617134866719,918321070.6284192],[1617138697011,960178009.2986945],[1617142067857,974105207.7725881],[1617146083923,973959760.0729104],[1617149999086,959500047.5209063],[1617153094367,1007753562.6156206],[1617156698445,1021534121.1115336],[1617160175611,1028067427.0339341],[1617163928330,1007755251.8882328],[1617166924538,1023240773.0466446],[1617171886674,1037535813.1806505],[1617175133694,1101375379.7094195],[1617178435173,1136688478.90344],[1617182857658,1208366620.2561867],[1617185353773,1208823054.3509212],[1617188828477,1234197192.568771],[1617193393471,1707076315.380663],[1617196301983,1845668637.7358408],[1617199516026,1901877634.1385415],[1617203681947,2015292037.1305778],[1617207515426,2141098631.115179],[1617210224998,2343473154.2871637],[1617214323265,2329074198.4966955],[1617217968405,2461828129.1798186],[1617221653017,2493042958.539376],[1617224582971,2532015555.7692595],[1617228589364,2508661361.110037],[1617232204720,2590057969.924583],[1617235260464,2749780924.550207],[1617239367664,2791689438.967896],[1617243152558,2778422749.5901804],[1617246573894,2802892972.2612605],[1617250114952,2795446026.902383],[1617253276300,2837092221.188881],[1617257741390,2957061611.281718],[1617261111556,3025594776.954216],[1617264301698,3140730366.12618],[1617267704421,3230797741.627739],[1617272276500,3247001347.7404704],[1617275862720,3182990384.8873067],[1617279129292,2889317168.9977646],[1617283053665,2753527702.506779],[1617287046529,2700392654.8781624],[1617290204012,2616296684.424929],[1617293298853,2494255828.9768047],[1617296557242,2383424694.8900166],[1617301325511,2288268623.177356],[1617303766777,2297155897.636895],[1617307669347,2314935325.319679],[1617311721980,2259716784.056617],[1617314946823,2267889595.9127536],[1617319572007,2174169254.528509],[1617323182318,2097690604.8152165],[1617326033792,2110975746.1916978],[1617329489226,2126100629.800452],[1617332409284,2193182655.044224],[1617337211709,2199847063.5248647],[1617340611316,2167549077.601362],[1617344146863,2110348803.8388174],[1617347361962,2023115590.5637138],[1617351380142,1864316761.5098753],[1617354151186,1788973202.0040677],[1617359277447,1731207666.0376515],[1617361312976,1418566500.3106787],[1617366169158,1693859181.5518322],[1617369860769,1656689094.290342],[1617372306072,1660176536.7450612],[1617376754676,1722154482.4234965],[1617379285817,1915067128.493045],[1617383311995,1982773491.2907202],[1617387963188,1985155493.939231],[1617391564495,1827213471.6221747],[1617395202777,1932891922.7380657],[1617398214973,1937931474.560893],[1617401809690,1961473630.4188676],[1617405699909,1952347409.661483],[1617409553080,2172811188.054834],[1617412963837,2431917537.219363],[1617416445822,2666886575.1140027],[1617420431122,2769520722.4907126],[1617422613890,2797409323.779513],[1617427393260,2895546310.6951184],[1617431058021,2894169435.883223],[1617433696700,2651591430.614699],[1617437513773,3448548871.8910036],[1617441138039,3537764498.5278754],[1617444820385,3662623380.0181885],[1617448128419,3729999481.3895626],[1617452094944,3741683833.307362],[1617457034540,3761774670.321721],[1617460631688,3809173022.555833],[1617464335978,3711591162.8519845],[1617467879738,3759143118.4621553],[1617471447610,3693936894.7524076],[1617474960418,3833857114.2069917],[1617478639837,3888109113.59996],[1617482233320,3857034438.9984646],[1617485821346,3898924734.2645984],[1617489477282,3952661186.2182713],[1617493109729,4002501827.9437523],[1617495709286,3872814933.0218143],[1617499443431,3939579930.8108554],[1617503699037,3663106636.5813146],[1617507443725,3808705623.491391],[1617510706891,3786240536.055139],[1617512446242,3717882675.3539762],[1617516040645,3722966733.2957063],[1617519813304,3482249884.952562],[1617523351916,3345586253.508183],[1617526909722,3327000473.8244348],[1617530664916,3181835266.2617188],[1617534176048,3094776290.1306324],[1617537924632,3064167829.684326],[1617541493704,3112790145.252149],[1617545018360,2989449570.670528],[1617548594506,3016965749.017692],[1617552471191,2973530338.557288],[1617555933696,2759208177.1915674],[1617559387440,2662906186.1813793],[1617563034515,2521716547.9565806],[1617566483711,2454800946.788864],[1617570325792,2412175803.4922743],[1617573668989,2381142461.766321],[1617577282876,2228904400.2017546],[1617580896737,2203439508.717633],[1617584514686,2083961834.3200803],[1617588367701,1922511436.832222],[1617591869391,1816453643.1859522],[1617595346098,1783362433.1356776],[1617599069131,1767878927.408502],[1617602711113,1782121869.0062866],[1617606278078,1784322317.8294444],[1617609891135,1785304724.1970084],[1617613319383,1792007217.4012969],[1617617302304,1808002080.6732872],[1617620901014,1821923720.87615],[1617624265084,1769426364.6123836],[1617629555312,1731155926.337212],[1617631504259,1735378701.9021676],[1617635133537,1942437073.2385755],[1617638780500,1938122743.6976163],[1617642119732,1932182393.8447528],[1617645707597,1918416705.3436842],[1617649325384,1925855235.7182896],[1617653252063,1944708214.0244768],[1617656889033,1932665022.73478],[1617660329160,1943687775.1192245],[1617663683699,1971924479.2343264],[1617667435208,2101421530.2666874],[1617672769205,2175322213.812557],[1617674524812,2168578229.7784457],[1617678186353,2149217571.1759067],[1617681915267,2132725563.885806],[1617685469475,1907950838.2268875],[1617689189705,2026223167.4473426],[1617692670953,1991840998.8517568],[1617696101989,1958389716.0448081],[1617699877898,2027665770.2623076],[1617703590445,2045913908.1590445],[1617707076556,2057724347.183567],[1617710622851,1722203248.9530182],[1617714225215,2160140597.446546],[1617717905528,2192080372.5552874],[1617721488585,2199844279.449877],[1617724918808,2244159138.5689125],[1617728548093,2263548854.897557],[1617732187891,2106855536.9938018],[1617735969816,2268365061.664965],[1617739538518,1863113060.588111],[1617742875565,2296819840.9881096],[1617746516853,2308037223.56185],[1617750327052,2297405821.9954567],[1617754017835,2215648462.217197],[1617758617023,2112353884.9607923],[1617761085616,2094123582.0260437],[1617764518134,2101292245.7045105],[1617768287923,2104106865.0792534],[1617771810289,2127056476.4717],[1617775566730,2152196953.3590703],[1617778865860,2160666464.579131],[1617782881414,2201171213.1865735],[1617786249160,2203934869.139618],[1617789807394,2329117281.806726],[1617793383957,2333039138.899913],[1617796986959,2491205752.3653517],[1617800521125,2652604590.3673797],[1617804331429,2692817000.168284],[1617807822435,2121796914.212729],[1617811418506,2538097921.330415],[1617815037057,2572049083.87979],[1617818698211,2550478468.4248347],[1617822347031,2541491737.3311806],[1617825969097,2609118564.630648],[1617829326876,2651351577.1099257],[1617833305171,2429954572.560337],[1617837011298,2435043578.3313527],[1617840572965,2394428204.082167],[1617843841041,2446826032.07983],[1617848315742,2395082349.188743],[1617850339793,2376349751.741466],[1617852591890,2385498650.2366877],[1617855126472,2380054416.699361],[1617858732962,2424505564.216302],[1617862619633,2434391633.272485],[1617865876330,2410962812.9744062],[1617869233838,2516114320.406959],[1617872539799,2437748581.3302546],[1617876293610,2247205079.171164],[1617880005259,2149347865.150653],[1617883394235,1893777066.5168178],[1617886836203,1757412804.559377],[1617892197847,1668727963.8671286],[1617894162445,1631584545.4824028],[1617897737215,1596293896.725426],[1617901282046,1525523967.3370435],[1617905003853,1370316987.26801],[1617908631874,1358993841.079183],[1617912335250,1404691449.9164236],[1617915995319,1379405950.1047523],[1617919567600,1366246502.7408085],[1617923270275,1289254721.1461022],[1617926622919,1386402238.6371279],[1617930228859,1384851642.1789908],[1617933705891,1365548610.2907162],[1617937372258,1357266138.9978309],[1617941122560,1335764096.6047564],[1617944870896,1322495289.1105938],[1617948462328,1283751933.8339043],[1617951863802,1272489837.990008],[1617955666499,1259096045.8789752],[1617958890026,1247182948.0102005],[1617962609987,1220448763.9536679],[1617966256703,1222538618.147044],[1617969964555,1148194206.4734476],[1617973333279,1199996169.7479842],[1617977646106,1154935691.529977],[1617980504476,1144564005.003322],[1617984273306,1132822242.6037295],[1617987925282,1136733019.0246003],[1617991396077,1139090847.1565342],[1617994822351,1133169530.4839995],[1617998615234,1113274570.5832539],[1618002141094,1094805189.6349592],[1618005876460,1035579604.067034],[1618009282025,1090335224.3969038],[1618013035782,1063984405.5106469],[1618016519119,1058097513.8615906],[1618020114108,1065381128.0365001]]}}
When this code invoked it logs data correctly but i can not return it at last. Anyone can help?
The problem appears to be that you're trying to return the entire Axios response. This cannot be serialised as JSON due to circular references.
Simply return the response data instead. You can also make your URL construction simpler (and safer) using the params option
exports.getDatas = functions.https.onCall(async ({ name, ts1, ts2 }) => {
functions.logger.log(name);
// 👇 note the destructure here
const { data } = await axios.get(
`https://api.coingecko.com/api/v3/coins/${encodeURIComponent(name)}/market_chart/range`,
{
params: {
vs_currency: "usd",
from: ts1,
to: ts2,
}
}
);
functions.logger.log(data);
return { data };
});

How to separate clients in an event based websocket implementation?

I'm writing my own event-based websocket wrapper, based on the ws package for node and having trouble separating clients on the server side.
I set up a test scenario where my client emits a message to the server and the server sends a "ping" back to that same client.
What happens is that my test scenario works perfectly with the first connected client, but as soon as another client connects, emit messages from the first client will ping to the other client (messages from second client will correctly ping to the second client).
It feels like the WebSocket is somehow shared between the two clients but I can't seem to find where this is happening.
//SERVER CODE
let events = {};
function WebSockServer(port) {
//Init server
const wss = new WebSocket.Server({
port,
clientTracking: true
}, () => {
if (events['open']) {
events['open'].callback();
}
});
wss.on('connection', ws => {
ws.id = uuidv4();
let sock = new WebSock(ws, wss);
if (events['connection']) {
events['connection'].callback(sock);
}
ws.on('message', json => {
console.log('received message from ' + ws.id);
const message = JSON.parse(json);
//Check flags
for (let key in message.flags) {
if (key === 'binary' && message.flags[key].length > 0) {
message.flags[key].forEach(binary => {
const parsed = Buffer.from(message.data[binary], 'utf-16');
message.data[binary] = parsed;
});
}
}
//Check if event handler exists & check if event is only to be triggered once
if (events[message.event] && !events[message.event].once) {
events[message.event].callback(message.data);
}
else if (events[message.event] && events[message.event].once) {
events[message.event].callback(message.data);
delete events[message.event];
}
else {
return;
}
});
ws.on('close', () => {
if (events['close']) {
console.log('client disconnected');
events['close'].callback(ws.id);
}
wss.clients.delete(ws);
});
});
//Create an event handler
this.on = function on(event, callback) {
events[event] = {callback, once: false};
return this;
}
wss.on('error', err => {
console.log('Server shut down.');
});
}
function WebSock(ws, wss) {
this.ws = ws;
this.id = ws.id;
//Create an event handler
this.on = function on(event, callback) {
events[event] = {callback, once: false};
return this;
}
//Create an event handler for one time use
this.once = function once(event, callback) {
events[event] = {callback, once: true};
return this;
}
//Emit message to socket
this.emit = function emit(event, data) {
let flags = {
binary: []
};
//Check for binary data
for (let key in data) {
if (Buffer.isBuffer(data[key])) {
const stringified = data[key].toJSON();
data[key] = stringified;
flags.binary.push(key);
}
}
const payload = JSON.stringify({event, data, flags});
this.ws.send(payload);
return this;
}
//Emit message to specific socket
this.emitTo = function emitTo(id, event, data) {
let destination;
let flags = {
binary: []
};
//Find socket
for (let socket of wss.clients) {
if (socket.id === id) {
destination = socket;
break;
}
}
//Check for binary data
for (let key in data) {
if (Buffer.isBuffer(data[key])) {
const stringified = data[key].toJSON();
data[key] = stringified;
flags.binary.push(key);
}
}
//Send message to socket
if (destination) {
//Check type
if (typeof event != 'string' || typeof data != 'object') {
throw new TypeError('event must be a string, data must be an object');
}
const payload = JSON.stringify({event, data, flags});
destination.send(payload);
return this;
}
}
}
module.exports = WebSockServer;
//CLIENT CODE
function webSock(url) {
const ws = new WebSocket(url);
let events = {};
//Create an event handler
this.on = function on(event, callback) {
events[event] = {callback, once: false};
return this;
}
//Create an event handler for one time use
this.once = function once(event, callback) {
events[event] = {callback, once: true};
return this;
}
//Emit message to server
this.emit = function emit(event, data) {
let flags = {
binary: []
};
//Check for binary data
for (let key in data) {
if (Buffer.isBuffer(data[key])) {
const stringified = data[key].toJSON();
data[key] = stringified;
flags.binary.push(key);
}
}
const payload = JSON.stringify({event, data, flags});
ws.send(payload);
return this;
}
ws.on('open', () => {
if (events['open']) {
events['open'].callback(ws);
}
});
ws.on('close', () => {
if (events['close']) {
events['close'].callback();
}
})
ws.on('message', json => {
const message = JSON.parse(json);
//Check flags
for (let key in message.flags) {
if (key === 'binary' && message.flags[key].length > 0) {
message.flags[key].forEach(buffer => {
const parsed = Buffer.from(message.data[buffer]);
message.data[buffer] = parsed;
});
}
}
//Check if event handler exists & check if event is only to be triggered once
if (events[message.event] && !events[message.event].once) {
events[message.event].callback(message.data);
}
else if (events[message.event] && events[message.event].once) {
events[message.event].callback(message.data);
delete events[message.event];
}
else {
return;
}
});
}
module.exports = webSock;
Any help would be much appreciated, I'm sure I'm missing something obvious.

TypeError: Cannot read property 'charCodeAt' of undefined - Button sometimes does not work

I'm updating a Facebook ChatBot to DialogFlow Version 2. I have a problem with buttons, they don't work the first time, but if the user sends a text message, and then try again, the buttons start working. I'm working whit Heroku and Node.js, these are the results of heroku log
This is my function sendToDialogFlow
async function sendToDialogFlow(sender, textString, params) {
try {
const sessionPath = sessionClient.sessionPath(
config.GOOGLE_PROJECT_ID,
sessionIds.get(sender)
);
const request = {
session: sessionPath,
queryInput: {
text: {
text: textString,
languageCode: config.DF_LANGUAGE_CODE,
},
},
queryParams: {
payload: {
data: params
}
}
};
const responses = await sessionClient.detectIntent(request);
const result = responses[0].queryResult;
handleDialogFlowResponse(sender, result);
} catch (e) {
console.log('error');
console.log(e);
}
}
And here it is handleDialogFlowResponse function
function handleDialogFlowResponse(sender, response) {
let responseText = response.fulfillmentMessages.fulfillmentText;
let messages = response.fulfillmentMessages;
let action = response.action;
let contexts = response.outputContexts;
let parameters = response.parameters;
var delay = 4000;
if (isDefined(action)) {
sendTypingOn(sender);
setTimeout(function(){
sendTypingOff(sender);
handleDialogFlowAction(sender, action, messages, contexts, parameters);
},delay);
} else if (isDefined(messages) && (messages.length == 1 && messages[0].type != 0 || messages.length > 1) ) {
sendTypingOn(sender);
setTimeout(function(){
sendTypingOff(sender);
handleMessages(messages, sender);
},delay);
} else if (responseText == '' && !isDefined(action)) {
} else if (isDefined(responseText)) {
sendTypingOn(sender);
setTimeout(function(){
sendTypingOff(sender);
sendTextMessage(sender, responseText);
},delay);
}
}
Thank you

Rewrite event emitter with Reactive programming(Semaphore example)

I'm use event emitters as synchronization primitives. For example I have one class which asks semaphore like structure in Redis. If semaphore is set it emits an event. The code is listed bellow:
var redis = require("redis"),
async = require('async'),
client = redis.createClient(),
assert = require('assert'),
EventEmitter = require('events').EventEmitter;
util = require('util');
var isMaster = false,
SEMAPHORE_ADDRESS = 'semaphore';
var SemaphoreAsker = function() {
var self = this;
var lifeCycle = function (next) {
client.set([SEMAPHORE_ADDRESS, true, 'NX', 'EX', 5], function(err, val) {
console.log('client');
if(err !== null) { throw err; }
if(val === 'OK') {
self.emit('crown');
} else {
console.log('still a minion');
}
});
};
async.forever(
function(next) {
setTimeout(
lifeCycle.bind(null, next),
1000
);
}
);
};
util.inherits(SemaphoreAsker, EventEmitter);
(new SemaphoreAsker()).on('crown', function() {
console.log('I`m master');
});
It works but looks a little bit heavy. Is it possible to rewrite the example with BaconJS(RxJS/whateverRPlibrary)?
The following should work in RXJS:
var callback = Rx.Observable.fromNodeCallback(client.set, client);
var source = Rx.Observable.interval(1000)
.selectMany(function() {
return callback([SEMAPHORE_ADDRESS, true, 'NX', 'EX', 5]);
})
.filter(function(x) { return x === 'OK'; })
.take(1);
source.subscribe(function(x) {
console.log("I am master");
});
If you are willing to additionally include the rx-node module you can also keep your event emitter structure by using
var emitter = RxNode.toEventEmitter(source, 'crown');
emitter.on('crown', function(){});
emitter.on('error', function(){});
emitter.on('end', function(){});
I used the basic Bacon.fromBinder to create a custom stream for this. Without a working example this is a bit of guesswork, but hopefully this helps you.
var redis = require("redis"),
client = redis.createClient(),
assert = require('assert'),
Bacon = require('bacon');
var SEMAPHORE_ADDRESS = 'semaphore';
var SemaphoreAsker = function() {
return Bacon.fromBinder(function (sink) {
var intervalId = setInterval(pollRedis, 1000)
return function unsubscribe() {
clearInterval(intervalId)
}
function pollRedis() {
client.set([SEMAPHORE_ADDRESS, true, 'NX', 'EX', 5], function(err, val) {
if(err !== null) { sink(new Bacon.Error(err)) }
else if(val === 'OK') { sink(new Bacon.Next('crown'))
else { assert.fail(); }
}
}
})
}
SemaphoreAsker().take(1).onValue(function() {
console.log("I am master")
})
The #paulpdanies answer but rewritten with Bacon:
var source = Bacon.interval(1000).flatMap(function() {
return Bacon.fromNodeCallback(
client, 'set', [SEMAPHORE_ADDRESS, true, 'NX', 'EX', 1]
);
})
.filter(function(x) { return x === 'OK'; })
.take(1);
source.onValue(function(x) {
console.log(x);
});

How can I intercept XMLHttpRequests from a Greasemonkey script?

I would like to capture the contents of AJAX requests using Greasemonkey.
Does anybody know how to do this?
The accepted answer is almost correct, but it could use a slight improvement:
(function(open) {
XMLHttpRequest.prototype.open = function() {
this.addEventListener("readystatechange", function() {
console.log(this.readyState);
}, false);
open.apply(this, arguments);
};
})(XMLHttpRequest.prototype.open);
Prefer using apply + arguments over call because then you don't have to explicitly know all the arguments being given to open which could change!
How about modifying the XMLHttpRequest.prototype.open or send methods with replacements which set up their own callbacks and call the original methods? The callback can do its thing and then call the callback the original code specified.
In other words:
XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open;
var myOpen = function(method, url, async, user, password) {
//do whatever mucking around you want here, e.g.
//changing the onload callback to your own version
//call original
this.realOpen (method, url, async, user, password);
}
//ensure all XMLHttpRequests use our custom open method
XMLHttpRequest.prototype.open = myOpen ;
Tested in Chrome 55 and Firefox 50.1.0
In my case I wanted to modify the responseText, which in Firefox was a read-only property, so I had to wrap the whole XMLHttpRequest object. I haven't implemented the whole API (particular the responseType), but it was good enough to use for all of the libraries I have.
Usage:
XHRProxy.addInterceptor(function(method, url, responseText, status) {
if (url.endsWith('.html') || url.endsWith('.htm')) {
return "<!-- HTML! -->" + responseText;
}
});
Code:
(function(window) {
var OriginalXHR = XMLHttpRequest;
var XHRProxy = function() {
this.xhr = new OriginalXHR();
function delegate(prop) {
Object.defineProperty(this, prop, {
get: function() {
return this.xhr[prop];
},
set: function(value) {
this.xhr.timeout = value;
}
});
}
delegate.call(this, 'timeout');
delegate.call(this, 'responseType');
delegate.call(this, 'withCredentials');
delegate.call(this, 'onerror');
delegate.call(this, 'onabort');
delegate.call(this, 'onloadstart');
delegate.call(this, 'onloadend');
delegate.call(this, 'onprogress');
};
XHRProxy.prototype.open = function(method, url, async, username, password) {
var ctx = this;
function applyInterceptors(src) {
ctx.responseText = ctx.xhr.responseText;
for (var i=0; i < XHRProxy.interceptors.length; i++) {
var applied = XHRProxy.interceptors[i](method, url, ctx.responseText, ctx.xhr.status);
if (applied !== undefined) {
ctx.responseText = applied;
}
}
}
function setProps() {
ctx.readyState = ctx.xhr.readyState;
ctx.responseText = ctx.xhr.responseText;
ctx.responseURL = ctx.xhr.responseURL;
ctx.responseXML = ctx.xhr.responseXML;
ctx.status = ctx.xhr.status;
ctx.statusText = ctx.xhr.statusText;
}
this.xhr.open(method, url, async, username, password);
this.xhr.onload = function(evt) {
if (ctx.onload) {
setProps();
if (ctx.xhr.readyState === 4) {
applyInterceptors();
}
return ctx.onload(evt);
}
};
this.xhr.onreadystatechange = function (evt) {
if (ctx.onreadystatechange) {
setProps();
if (ctx.xhr.readyState === 4) {
applyInterceptors();
}
return ctx.onreadystatechange(evt);
}
};
};
XHRProxy.prototype.addEventListener = function(event, fn) {
return this.xhr.addEventListener(event, fn);
};
XHRProxy.prototype.send = function(data) {
return this.xhr.send(data);
};
XHRProxy.prototype.abort = function() {
return this.xhr.abort();
};
XHRProxy.prototype.getAllResponseHeaders = function() {
return this.xhr.getAllResponseHeaders();
};
XHRProxy.prototype.getResponseHeader = function(header) {
return this.xhr.getResponseHeader(header);
};
XHRProxy.prototype.setRequestHeader = function(header, value) {
return this.xhr.setRequestHeader(header, value);
};
XHRProxy.prototype.overrideMimeType = function(mimetype) {
return this.xhr.overrideMimeType(mimetype);
};
XHRProxy.interceptors = [];
XHRProxy.addInterceptor = function(fn) {
this.interceptors.push(fn);
};
window.XMLHttpRequest = XHRProxy;
})(window);
You can replace the unsafeWindow.XMLHttpRequest object in the document with a wrapper. A little code (not tested):
var oldFunction = unsafeWindow.XMLHttpRequest;
unsafeWindow.XMLHttpRequest = function() {
alert("Hijacked! XHR was constructed.");
var xhr = oldFunction();
return {
open: function(method, url, async, user, password) {
alert("Hijacked! xhr.open().");
return xhr.open(method, url, async, user, password);
}
// TODO: include other xhr methods and properties
};
};
But this has one little problem: Greasemonkey scripts execute after a page loads, so the page can use or store the original XMLHttpRequest object during it's load sequence, so requests made before your script executes, or with the real XMLHttpRequest object wouldn't be tracked by your script. No way that I can see to work around this limitation.
I spent quite some time figuring out how to do this.
At first I was just overriding window.fetch but that stopped working for some reason - I believe it has to do with Tampermonkey trying to sandbox window (??) and I also tried unsafeWindow with the same results.
So. I started looking into overriding the requests at a lower level. The XMLHttpRequest (also that class name upper case lower case ew...)
Sean's answer was helpful to get started but didn't show how to override the responses after interception. The below does that:
let interceptors = [];
/*
* Add a interceptor.
*/
export const addInterceptor = (interceptor) => {
interceptors.push(interceptor);
};
/*
* Clear interceptors
*/
export const clearInterceptors = () => {
interceptors = [];
};
/*
* XML HTPP requests can be intercepted with interceptors.
* Takes a regex to match against requests made and a callback to process the response.
*/
const createXmlHttpOverride = (
open
) => {
return function (
method: string,
url,
async,
username,
password
) {
this.addEventListener(
"readystatechange",
function () {
if (this.readyState === 4) {
// Override `onreadystatechange` handler, there's no where else this can go.
// Basically replace the client's with our override for interception.
this.onreadystatechange = (function (
originalOnreadystatechange
) {
return function (ev) {
// Only intercept JSON requests.
const contentType = this.getResponseHeader("content-type");
if (!contentType || !contentType.includes("application/json")) {
return (
originalOnreadystatechange &&
originalOnreadystatechange.call(this, ev)
);
}
// Read data from response.
(async function () {
let success = false;
let data;
try {
data =
this.responseType === "blob"
? JSON.parse(await this.response.text())
: JSON.parse(this.responseText);
success = true;
} catch (e) {
console.error("Unable to parse response.");
}
if (!success) {
return (
originalOnreadystatechange &&
originalOnreadystatechange.call(this, ev)
);
}
for (const i in interceptors) {
const { regex, override, callback } = interceptors[i];
// Override.
const match = regex.exec(url);
if (match) {
if (override) {
try {
data = await callback(data);
} catch (e) {
logger.error(`Interceptor '${regex}' failed. ${e}`);
}
}
}
}
// Override the response text.
Object.defineProperty(this, "responseText", {
get() {
return JSON.stringify(data);
},
});
// Tell the client callback that we're done.
return (
originalOnreadystatechange &&
originalOnreadystatechange.call(this, ev)
);
}.call(this));
};
})(this.onreadystatechange);
}
},
false
);
open.call(this, method, url, async, username, password);
};
};
const main = () => {
const urlRegex = /providers/; // Match any url with "providers" in the url.
addInterceptor({
urlRegex,
callback: async (_data) => {
// Replace response data.
return JSON.parse({ hello: 'world' });
},
override: true
});
XMLHttpRequest.prototype.open = createXmlHttpOverride(
XMLHttpRequest.prototype.open
);
};
main();
Based on proposed solution I implemented 'xhr-extensions.ts' file which can be used in typescript solutions.
How to use:
Add file with code to your solution
Import like this
import { XhrSubscription, subscribToXhr } from "your-path/xhr-extensions";
Subscribe like this
const subscription = subscribeToXhr(xhr => {
if (xhr.status != 200) return;
... do something here.
});
Unsubscribe when you don't need subscription anymore
subscription.unsubscribe();
Content of 'xhr-extensions.ts' file
export class XhrSubscription {
constructor(
private callback: (xhr: XMLHttpRequest) => void
) { }
next(xhr: XMLHttpRequest): void {
return this.callback(xhr);
}
unsubscribe(): void {
subscriptions = subscriptions.filter(s => s != this);
}
}
let subscriptions: XhrSubscription[] = [];
export function subscribeToXhr(callback: (xhr: XMLHttpRequest) => void): XhrSubscription {
const subscription = new XhrSubscription(callback);
subscriptions.push(subscription);
return subscription;
}
(function (open) {
XMLHttpRequest.prototype.open = function () {
this.addEventListener("readystatechange", () => {
subscriptions.forEach(s => s.next(this));
}, false);
return open.apply(this, arguments);
};
})(XMLHttpRequest.prototype.open);
Not sure if you can do it with greasemonkey, but if you create an extension then you can use the observer service and the http-on-examine-response observer.

Categories

Resources