Hubot with slack adapter - cannot perform rtm.start - http

I'm trying to have hubot + slack on my local machine.
installed hubot and slack client.
running:
bin\hubot -a slack
and got error (after adding log messages to the script)
INFO Connecting...
INFO { ok: false, error: { [Error: socket hang up] code:
'ECONNRESET' } }
from reading code in node_modules\slack-client\src\client.js
found the problem occurs in a POST request:
Client.prototype.login = function() {
this.logger.info('Connecting...');
return this._apiCall('rtm.start', {
agent: 'node-slack'
}, this._onLogin); };
Client.prototype._apiCall = function(method, params, callback) {
var options, post_data, req;
params['token'] = this.token;
post_data = querystring.stringify(params);
options = {
hostname: this.host,
method: 'POST',
path: '/api/' + method,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
req = https.request(options);
tried to do: Node.js POST causes [Error: socket hang up] code: 'ECONNRESET'
with no success

Related

Deno serve imported from std/http/server.ts is not async iterable?

Here's the entirety of my .js file:
import { serve } from "https://deno.land/std/http/server.ts"
let server = serve({ port: 4000 })
for await (const req of server){
console.log('literally anything')
}
I'm using entirely code which i've seen multiple other people run without issues, and i have myself ran similar for loops before on this same machine. I don't understand what i broke, or if i'm importing the wrong thing, i have no idea what the right thing is. I'm on Local Deno version 1.18.1, the path is the one i get from the deno.land site, and the error i get when i try deno run --allow-net on that code is:
error: Uncaught TypeError: server is not async iterable
for await (const req of server){
at file:///H:/proj/testapp/serveHTTP.js:4:25
The return type of serve used to be Server (which is async iterable) up until std version 0.106.0: here's a link to that version of serve. That's probably why you've seen examples using it that way.
Starting in version 0.107.0 of std, the signature of serve changed to accept a Handler instead (and return Promise<void>).
Here's a link to the documentation for the current version of serve (from std#0.123.0), and here's an example of how to use it:
so-70963882.ts:
import { serve } from "https://deno.land/std#0.123.0/http/server.ts";
function requestHandler (request: Request): Response {
const data = {
url: request.url,
headers: Object.fromEntries([...request.headers].sort()),
};
console.log(data);
const body: BodyInit = JSON.stringify(data, null, 2);
const headers = new Headers([['content-type', 'application/json']]);
const init: ResponseInit = {headers};
return new Response(body, init);
}
const ac = new AbortController();
serve(requestHandler, { port: 4000, signal: ac.signal });
const responseText = await (await fetch('http://localhost:4000')).text();
console.log(responseText);
ac.abort();
In the console:
deno run --allow-net ./so-70963882.ts
{
url: "http://localhost:4000/",
headers: {
accept: "*/*",
"accept-encoding": "gzip, br",
host: "localhost:4000",
"user-agent": "Deno/1.18.1"
}
}
{
"url": "http://localhost:4000/",
"headers": {
"accept": "*/*",
"accept-encoding": "gzip, br",
"host": "localhost:4000",
"user-agent": "Deno/1.18.1"
}
}
You should always use versioned URLs — which are more likely to "be immutable" (provide idempotent responses) — for imported modules whenever possible.

REST API call using nodejs on localhost

I have made a REST API using R language.
#* #get /mean
normalMean <- function(samples=10){
data <- rnorm(samples)
mean(data)
}
I started the R server and tested the API using the url- http://localhost:8000/mean and it is working.
However when I tried to invoke the API using nodejs it returns an error:
Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1124:19)
at TLSSocket.g (events.js:292:16)
at emitNone (events.js:91:20)
at TLSSocket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
Here is the nodejs code:
var https = require('https');
var optionsget = {
host : 'localhost', // here only the domain name
// (no http/https !)
port : 8000,
path : '/mean', // the rest of the url with parameters if needed
method : 'GET' // do GET
};
console.info('Options prepared:');
console.info(optionsget);
console.info('Do the GET call');
var reqGet = https.request(optionsget, function(res) {
console.log("statusCode: ", res.statusCode);
// uncomment it for header details
// console.log("headers: ", res.headers);
res.on('data', function(d) {
console.info('GET result:\n');
process.stdout.write(d);
console.info('\n\nCall completed');
});
});
I am not understanding where I am going wrong. I intend to make a put request in a similar manner after this.
It means that socket does not send connection end event within the timeout period. If you are getting the request via http.request (not http.get). You have to call request.end() to finish sending the request.
https.get('http://localhost:8000/mean', (resp) => {
console.log("statusCode: ", res.statusCode);
let result = 0;
// on succ
resp.on('data', (d) => {
result = d;
});
// on end
resp.on('end', () => {
console.log(result);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});

How to send consecutive requests with HTTP keep-alive in node.js?

I'm using node.js 0.6.18, and the following code makes node.js close the TCP connection between every two requests (verified with strace on Linux). How do I make node.js reuse the same TCP connection for multiple HTTP requests (i.e. keep-alive)? Please note that the webserver is capable of keep-alive, it works with other clients. The webserver returns a chunked HTTP response.
var http = require('http');
var cookie = 'FOO=bar';
function work() {
var options = {
host: '127.0.0.1',
port: 3333,
path: '/',
method: 'GET',
headers: {Cookie: cookie},
};
process.stderr.write('.')
var req = http.request(options, function(res) {
if (res.statusCode != 200) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
process.exit(1)
}
res.setEncoding('utf8');
res.on('data', function (chunk) {});
res.on('end', function () { work(); });
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
process.exit(1);
});
req.end();
}
work()
I was able to get this to work (verified with strace) by creating an http.Agent and setting its maxSockets property to 1. I don't know if this is the ideal way to do it; however, it does meet the requirements. One thing that I did notice is that what the docs claimed about http.Agent behavior did not accurately describe how it worked in practice. Code below:
var http = require('http');
var cookie = 'FOO=bar';
var agent = new http.Agent;
agent.maxSockets = 1;
function work() {
var options = {
host: '127.0.0.1',
port: 3000,
path: '/',
method: 'GET',
headers: {Cookie: cookie},
agent: agent
};
process.stderr.write('.')
var req = http.request(options, function(res) {
if (res.statusCode != 200) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
process.exit(1)
}
res.setEncoding('utf8');
res.on('data', function (chunk) {});
res.on('end', function () { work(); });
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
process.exit(1);
});
req.end();
}
work()
EDIT: I should add that I did my testing with node.js v0.8.7
you can just set:
http.globalAgent.keepAlive = true

Sending http request in node.js

I am trying to send a http request to a neo4j database using node.js. This is the code I am using:
var options = {
host: 'localhost',
port: 7474,
path: '/db/data',
method: 'GET',
headers: {
accept: 'application/json'
}
};
console.log("Start");
var x = http.request(options,function(res){
console.log("Connected");
res.on('data',function(data){
console.log(data);
});
});
I check out that the database is running (I connect to the administration web page and everything is working). I am afraid that the problem is not on the database side but on the node.js side.
I hope some could give some light about this issue. I want to learn how to send a http request in node.js, the answer does not have to be specific to the neo4j issue.
Thanks in advance
If it's a simple GET request, you should use http.get()
Otherwise, http.request() needs to be closed.
var options = {
host: 'localhost',
port: 7474,
path: '/db/data',
method: 'GET',
headers: {
accept: 'application/json'
}
};
console.log("Start");
var x = http.request(options,function(res){
console.log("Connected");
res.on('data',function(data){
console.log(data);
});
});
x.end();
I highly recommend to you use this minimal and easy package to send request on nodejs
Install package
npm install smoothly-request
Code that sends request
const smoothlyRequest = require('smoothly-request');
(async () => {
const result = await smoothlyRequest({
hostname: `http://localhost:7474`,
path: '/db/data',
method: 'GET'
});
})();

Listen and request from same port in node.js

I am testing an XML-RPC set up in node.js and would like to test the server receiving calls and responding as well as the client making calls to the server and receiving a response in the same node session. If I run http.createServer and http.request with the same host and port, I get:
Error: ECONNREFUSED, Connection refused
at Socket._onConnect (net.js:600:18)
at IOWatcher.onWritable [as callback] (net.js:186:12)
Test code that will generate the errror:
var http = require('http')
var options = {
host: 'localhost'
, port: 8000
}
// Set up server and start listening
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end('success')
}).listen(options.port, options.host)
// Client call
// Gets Error: ECONNREFUSED, Connection refused
var clientRequest = http.request(options, function(res) {
res.on('data', function (chunk) {
console.log('Called')
})
})
clientRequest.write('')
clientRequest.end()
While the code above will work if separated into two files and run as separate node instances, is there a way to get the above to run on the same node instance?
As it was mentioned above your http-server may not be running at the time you make a request. Using setTimeout is completely wrong. Use the callback parameter in listen method instead:
var http = require('http')
var options = {
host: 'localhost'
, port: 8000
}
// Set up server and start listening
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end('success')
}).listen(options.port, options.host, function() {
// Client call
// No error, server is listening
var clientRequest = http.request(options, function(res) {
res.on('data', function (chunk) {
console.log('Called')
})
})
clientRequest.write('')
clientRequest.end()
});
Your HTTP server probably isn't fully loaded and operational at the time when you are doing your request to it. Try wrap your client request with setTimeout to give your server a time to set up, for example like this:
var http = require('http')
var options = {
host: 'localhost'
, port: 8000
}
// Set up server and start listening
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end('success')
}).listen(options.port, options.host)
setTimeout(function() {
// Client call
// Shouldn't get error
var clientRequest = http.request(options, function(res) {
res.on('data', function (chunk) {
console.log('Called')
})
})
clientRequest.write('')
clientRequest.end()
}, 5000);

Resources