nodejs tls session id - node.js

I am using TLS to create session using node.js library. Node.js does it provide a way to retrieve session id of TLS connection established. It is part of SSL ctx in openssl.
Can it be done without using connect, express or geddy?

Unfortunately I don't think that information is exposed from the SSL context for node connections.
You can access the node object representing the context as follows:
var con = tls.connect(..., ...);
con.pair.credentials.context
Unfortunately, the only methods available on that object are setKey, setCert, addCACert, addCRL, addRootCerts, setCiphers and setOptions.
That said, with a little bit of C++ and SSL know-how and come copy/pasting, you could probably patch node's node_crypto.cc and node_crypto.h files to add that lookup without TOO much work.

You can't get the session_id but you can get the session itself for caching / resume purposes by calling conn.getSession() once the connection is established.

Related

How to use existing socket for a NodeJS HTTP server?

I made a proof of concept Reverse HTTP implementation using NodeJS.
However reusing client's socket required me to set a private member property; is there a correct way to do it?
server._socket = socket;
server.emit('connection', server._socket);
NodeJS HTTP docs tell about server.listen(socket), but it didn't work; it threw an exception about illegal parameter.
Full sample code for both client & server available at: https://github.com/norjs/portal-service/blob/12-reverse-http-support/samples/reverse-http/client.js#L57

Connect to a socket.io server from a Node.js server using the 'ws' package

I have a Node.js server which utilizes the popular ws package for using web sockets. I'd like to use this library to connect to an third party server which is running socket.io.
If I were to use socket.io on my server, the connection code would be something like this:
const socket = socketIo('https://api.example.com/1.0/scores')
I've attempted to connect to the same service using the ws package, and modifying the url:
const wsClient = new WebSocket('wss://api.example.com/1.0/scores');
but this results in the following:
Error: Unexpected server response: 200
Question:
What needs to be done to connect to a third party server running socket.io from a server running the ws package?
Additional Info:
I've noticed in my searches that some people have suggested appending
/socket.io/?EIO=3&transport=websocket to the end of the url. This
does not throw the same error as above (> Error: Unexpected server
response: 200) nor throw any visible error, but does not appear to
work (no data is received from the remote server).
Using new WebSocket('ws://api.example.com/1.0/scores?EIO=3&transport=websocket'); to open the connection (via ws) results in the following stack trace:
{ Error: Parse Error
at Socket.socketOnData
at emitOne
at Socket.emit
// ...
}
The socket.io api utilizes websockets but it also has a lot of other functions built on top of it in order to do things such as HTTP handshakes, session ids, and it can even handle fail overs to other protocols when needed.
You got half of the issue so far. Adding the line socket.io/?EIO=3&transport=websocket you're specifying parameters for the socket.io server to take.
EIO=3 specifies the version number for engine.io in which socket.io is using. In this case you are saying engine.io version = 3
transport=websocket specifies which transport protocol to use. As i said earlier, socket.io uses other protocols in cases such as fail overs. This portion forces socket.io to use websocket as the preferred protocol.
Now the next half is the WebSocket. WebSocket allows for Extensions which includes different kinds of compression that are commonly used when sending data. Which I believe is what is causing your Parse Error
Try this (found here):
const WebSocket = require('ws');
const ws = new WebSocket('ws://server/socket.io/?EIO=3&transport=websocket', {
perMessageDeflate: false
});
By setting perMessageDeflate: false you are specifying "Do not compress data". Since as i said this is a WebSocket Extension there are different variations as well. Try these instead if it doesn't work
x-webkit-deflate-frame
perframe-deflate
As a disclaimer this information is from the research that I have done. Im not a "socket.io specialist" so if there's anything incorrect please comment and i'll edit the post.
Because Socket.IO doesn't guarantee that there will be a WebSockets server hosted like you're seeming to expect, you should instead use their standard client package.
npm i socket.io-client
Then use the package in your code:
const ioClient = require('socket.io-client')('https://example.com/1.0/scores')
The full docs for socket.io-client are available on their GitHub repo.
Note: Honestly, though, it's just better at this point to use WebSockets instead if possible. WebSockets has become well-supported in browsers and is quite standard. Socket.IO is rarely necessary and could add some overhead.

How to change the AWS node client user agent?

I'm using the node aws-sdk package and I need to send a custom user agent in the S3 requests in order to identify the process in the console log.
I've seen a method to do this in the Java SDK but I can't see any similar in the node package.
Is there any way to do this easily?
After browsing in the source code I found an undocumented option to set the user agent: customUserAgent
const options = { customUserAgent: 'my-process-name' };
const client = new AWS.S3(options);
You can define an agent in the httpoptions field of the options you send to the constructor as per here:
httpOptions (map) — A set of options to pass to the low-level HTTP request.
Currently supported options are:
proxy [String] — the URL to proxy requests through
agent [http.Agent, https.Agent] — the Agent object to perform HTTP requests with. Used for connection pooling. Defaults to the global agent (http.globalAgent) for non-SSL connections. Note that for SSL connections, a special Agent object is used in order to enable peer certificate verification. This feature is only available in the Node.js environment.
connectTimeout [Integer] — Sets the socket to timeout after failing to establish a connection with the server after connectTimeout milliseconds. This timeout has no effect once a socket connection has been established.
timeout [Integer] — Sets the socket to timeout after timeout milliseconds of inactivity on the socket. Defaults to two minutes (120000).
xhrAsync [Boolean] — Whether the SDK will send asynchronous HTTP requests. Used in the browser environment only. Set to false to send requests synchronously. Defaults to true (async on).
Is that what you're looking for?

socket.io ensure state on client reconnection

I am currently working on a project with socket.io, and i'm not sure to fully understand the mechanism of reconnection.
Since a disconnection could happen client side, i would like to know how to maintain the state of the socket on the server. I already know that socket.io-client will try to reconnect automatically, but i would like to know if it is possible to ensure the state of the socket on the server side.
I was thinking of a cookie based session, with express for example, but again i am not sure if i'm taking the good way about this. Is there another solution i should consider?
For the record, i successfully configured HAProxy with a cookie based sticky-sessions mechanism. Could it be possible to mix this mechanism with a cookie session on the socket.io server ?
Thanks
William
I think cookie based sessions are your best option. Look into the session.socket.io module. Looks like it was built specifically for this.
var SessionSockets = require('session.socket.io');
var sessionSockets = new SessionSockets(io, sessionStore, cookieParser);
sessionSockets.on('connection', function (err, socket, session) {
//your regular socket.io code goes here
//and you can still use your io object
session.foo = 'bar';
//at this point the value is not yet saved into the session
session.save();
//now you can read session.foo from your express routes or connect middlewares
});
Alternatively you could implement sessions yourself using express as you mentioned. I don't know of any easy way to integrate with HAProxy.

Structure of Express application with Redis

I am unsure about where would be the best place to define the redis client in a Express application I am building. I am using skeleton as the framework.
It seems like the connection to redis should go in either boot.coffee or app.coffee, but then I can't easily get a reference to it in application_controller.coffee, which is where I need it.
If I put client = redis.createClient in application_controller.coffee, will that mean a new client is created on each request?
I would define the Redis client in app.coffee (after configuration, before the routes) and set the Redis client as a property on the App object:
app.client = redis.createClient
Then in application_controller.coffee you can access the Redis client by app.client.

Resources