How to configure nack/node on Rails project? - ruby-on-rails

Does any one Has every configure nack for the Rails Projects I happen to tried the dummy code
var http = require('http');
var nack = require('nack');
var app = nack.createProcess("/home/viren/myapp/config.ru");
http.createServer(function (req, res) { app.proxy(req, res); }).listen(8124, "127.0.0.1");
but it reported me with the following error
events.js:94
throw new Error('addListener only takes instances of Function');
^ Error: addListener only takes instances of Function
at BufferedRequest. (events.js:94:11)
at Process. (/home/viren/node_modules/nack/lib/process.js:257:21)
at Process.proxy (/home/viren/node_modules/nack/lib/process.js:3:63)
at Server. (/home/viren/simple.proxy.js:7:7)
at Server.emit (events.js:67:17)
at HTTPParser.onIncoming (http.js:1124:12)
at HTTPParser.onHeadersComplete (http.js:108:31)
at Socket.ondata (http.js:1019:22)
at Socket._onReadable (net.js:683:27)
at IOWatcher.onReadable [as callback] (net.js:177:10)
here is my custom rack-file
require "config/environment"
use Rails::Rack::LogTailer
use ActionDispatch::Static
run ActionController::Dispatcher.new

According the source at node_modules/nack/lib/process.js:257 nack is expecting app.proxy to have a signature of app.proxy(req, res, next) with is a common idiom with connect apps. In connect, calling next("some value") is a convention as most apps have a catch all error handler at the bottom of the middleware chain. Since your not using connect, just create your own error handler.
I also created a pull request, so hopefully using next will be optional in the future. https://github.com/josh/nack/pull/25
var http = require('http'); var nack = require('nack');
var app = nack.createProcess("/home/viren/myapp/config.ru");
http.createServer(function (req, res) { app.proxy(req, res, logNackError); }).listen(8124, "127.0.0.1");
function logNackError(err) {
console.log('nack error:', err);
}

Related

(XMLHttpRequest error) Problem with serverside CORS policy

I created a flutter project with a web version and we already have a server for database access that another android/ios app uses. However the web version of the new app is running into problems with cors policy. I've been trying to solve this looking at other stock overflow questions and searching on google without success and was hoping someone can help me figure out what I might be doing wrong.
I've tested making the uri client side both with:
String url = "https://" + host + ":" + port;
Uri uri = Uri.parse(url + "/test");
and
String url = host + ":" + port;
Uri uri = Uri.https(url, "/test");
I then call the server using the http/http package:
Response response = await get(uri).timeout(const Duration(seconds: 17));
As for the structure of the server side code:
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const https = require('https');
const routerOne = require('./path/to/router/file');
const routerTwo = require('./path/to/router/file');
const dotenv = require('dotenv');
const fs = require("fs");
dotenv.config();
console.log('port' + process.env.PORT);
var key = fs.readFileSync('./certs/key.key');
var cert = fs.readFileSync('./certs/cert.crt');
var options = {
key: key,
cert: cert
};
const cors = require('cors');
const app = express();
app.use(cors());
try {
let server = https.createServer(options, app);
server.listen(process.env.PORT, () => {
console.log('Started https server on port ' + process.env.PORT);
});
} catch (err) {
console.log(err);
}
app.get('/test', cors(), function (req, res, next) {
res.json({msg: "This is CORS-enabled for all origins!"})
})
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({limit: '50mb', extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/router/one', routerOne);
app.use('/router/two', routerTwo);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
console.log(err);
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Unlike android when running web version(Chrome or Edge), I have been unable to get the response from the newly added '/test' on the server side. I'm hoping for some suggestion for how I can get the cors policy to work.
Client side I've tried using Uri.https instead of Uri.parse and I added headers as well.
On the server I tried to follow instructions on how to add cors policy to node.js/express.
Error message from flutter:
Error: XMLHttpRequest error.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 963:28 get current
packages/http/src/browser_client.dart 69:22 <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1685:54 runUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 147:18 handleValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 766:44 handleValueCallback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 795:13 _propagateToListeners
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 557:7 [_complete]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/stream_pipe.dart 61:11 _cancelAndValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/stream.dart 1530:7 <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 334:14 _checkAndCall
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 339:39 dcall
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/html/dart2js/html_dart2js.dart 37309:58 <fn>
at Object.createErrorWithStack (http://localhost:59072/dart_sdk.js:5093:12)
at Error._throw (http://localhost:59072/dart_sdk.js:20399:18)
at Error.throwWithStackTrace (http://localhost:59072/dart_sdk.js:20396:18)
at async._AsyncCallbackEntry.new.callback (http://localhost:59072/dart_sdk.js:40921:18)
at Object._microtaskLoop (http://localhost:59072/dart_sdk.js:40778:13)
at _startMicrotaskLoop (http://localhost:59072/dart_sdk.js:40784:13)
at http://localhost:59072/dart_sdk.js:36261:9
Image of browser: image of browser with network tab
Update Solution
The answer from Ber is correct. This is a problem with certificate. Self signed certificate was being used on our server and by getting a new certificate using Let's encrypt the problem got solved. If anyone else runs into the "XMLHttpRequest error" they may also want to check out the error output in the browser as the "net::ERR_CERT_AUTHORITY_INVALID" was not shown in flutter.
The error code in your screen shot is net::ERR_CERT_AUTHORITY_INVALID
meaning the server's SSL certificate is expired, invalid for the domain or not accepted by the root certificates in your app.

Unable to establish connection between Node.JS and React-Native (Socket.IO)

I'm new to React and Node and i'm trying to make a simple WebSocket using Socket.IO which gonna simply send greetings to all connected users and the user will respond to the server.
The Node.JS server is running on a Windows PC while the React-Native app is running on both iOS and Android devices.
Node.JS server code is the following
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'block',
database : 'visualpos'
});
// Creating a GET route that returns data from the 'users' table.
app.get('/prenotazioni', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'users' table).
connection.query("SELECT Data, Importo_Doc FROM tabella_pagamenti", function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
connection.release();
});
});
app.get('/', function(req, res){
res.send('<h1>Hello World</h1>');
});
// Starting our server.
http.listen(3000, () => {
console.log('In ascolto sulla porta *:3000');
});
io.emit('saluta', 'Ciao dal server :)');
io.on('connected', (data) => {
console.log(data);
});
Actually GET part of the code works perfectly but the Socket.IO seems death.
The client doesn't get any response and server the same i think the Socket.IO server simply doesn't start..
In XCode Debug i get the following errors when the app is running on the iPhone
And i even get on both devices warning "Unrecognized WebSocket connection option(s) 'agent', 'perMessageDeflate',..."
And here is the code i'm using in React-Native
import io from 'socket.io-client'
var socket = io('http://192.168.100.50:3000', {
jsonp: false,
transports: ['websocket'],
autoConnect: true,
reconnection: true,
reconnectionDelay: 500,
reconnectionAttempts: Infinity
});
componentDidMount(){
socket.emit('connected','we');
socket.on('saluta',(data) => { alert(data); });
}
On socket.io getStarted section, they use a "connection" event instead of "connected" (https://socket.io/get-started/chat/).
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});

Exception ETIMEDOUT in node.js

I write application for iOS, which uses Socket.IO. Sometimes my server JS-script falls with this error:
events.js:85
throw er; // Unhandled 'error' event
^
Error: connect ETIMEDOUT
at exports._errnoException (util.js:746:11)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:983:19)
What I know is:
Script workes fine when I use only application for Android. That app uses Socket.IO for Android
Script workes fine when I use only web-client (yeap, with socket.IO)
Script startes to fall when I use iOS app.
Crash happens not always and not right away. Script falls after 5-10 minutes after connection and may crash, but may not.
So, I think the problem is in server library for socket.io, but exception fires only when iOS-client connecting.
How can I handle this exception?
UPDATE
There is problem was in the OAuth module on my node.js-server, which tried to check app token but had timeout to vk.com
I've edited vkapi module in my node.js server by adding "on" event for "https.get" function:
Was:
https.get(options, function(res) {
var apiResponse = new String();
res.setEncoding('utf8');
res.on('data', function(chunk) {
apiResponse += chunk;
});
res.on('end', function() {
var o = JSON.parse(apiResponse);
if (o.error) { self.emit('appServerTokenNotReady', o);
} else {
self.token = o.access_token;
self.emit('appServerTokenReady');
}
});
});
Now:
https.get(options, function(res) {
var apiResponse = new String();
res.setEncoding('utf8');
res.on('data', function(chunk) {
apiResponse += chunk;
});
res.on('end', function() {
var o = JSON.parse(apiResponse);
if (o.error) { self.emit('appServerTokenNotReady', o);
} else {
self.token = o.access_token;
self.emit('appServerTokenReady');
}
});
}).on('error', function(e) {
console.log('HTTPS error');
});
In general, you can handle these kinds of async errors by listening for the error event on whatever (e.g. request, connection, etc.) object.
The error event is special in that if there are currently no event handlers for it when it is emitted, the error will be thrown instead.

Can some one give be a sample code how to add a request handler to a HttpServer Object in dart?

I am very new to the dart programming any help is appreciated.
void main() {
var server = new HttpServer();
server.listen('127.0.0.1', 8080);
server.
addRequestHandler(
accept(HttpRequest function) => acceptInput(request, response), handler);
}
I want to add the function below to the request handler.
server.addrequestHandler()
I would like to do this so that I can add many request handlers as such including one for websockets
A sample or a tutorial would be very helpful.
I want to keep each handler in a separate function just for simplicity.
void acceptInput(HttpRequest request,HttpResponse response){
print(request.connectionInfo.toString());
print(request.queryParameters.toString());
response.outputStream.write('Hello dude'.charCodes);
response.outputStream.close();
}
Note:I know my void main code is wrong I need help to make it correct so that it incorporates the acceptInput Function.
Actually, you're really close.
Try this:
var server = new HttpServer();
server.addRequestHandler(
(req) => req.path == '/save',
handleSave);
server.addRequestHandler(
(req) => req.path == '/delete',
handleDelete);
server.defaultRequestHandler = new StaticFileHandler(basePath).onRequest;
Where handleSave and handleDelete are just functions, like:
handleSave(HttpRequest req, HttpResponse resp) {
// ...
}
Here is the code for a web server that serves files and handles web socket connections:
https://github.com/dart-lang/web-components-code-lab/blob/master/step04/bin/chat_server.dart
Does that answer your question?
You should check out at my implementation of Express.dart which is an Express-like web framework that fits in a single file so it's an easy read.
Check out the HttpServer docs to see the correct signatures for each method. This is the API for addRequestHandler:
abstract addRequestHandler(
bool matcher(HttpRequest request),
void handler(HttpRequest request, HttpResponse response)
)
The first parameter is whether this should handle the request, whilst the 2nd argument is the handler that will handle the request if the matcher is true.
So a Http app in Dart would look like:
var server = new HttpServer();
server.addRequestHandler(
(HttpRequest req) => true,
acceptInput);
server.listen('127.0.0.1', 8080);

how to parse a request in a node.js server built on net module

We are building a server with net module, and having hard time extracting the URL (and resource path) from the request. The following code crashes, saying:
Parameter 'url' must be a string not undefined.
File netServer.js:
var net = require('net');
var url = require('url');
var server = net.createServer(function(socket) { //'connection' listener
socket.on('connect', function(request) {
});
socket.on('data', function(request) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
});
socket.on('end', function() {
});
});
server.listen(8080, function() { //'listening' listener
console.log('server bound');
});
Any suggestions?
Are you trying to build an HTTP server? net is a TCP package, so all you get is the remoteAddress and remotePort, the rest will be sent on the data handler (which is just passed a Buffer, or a string, depending on the encoding).
Use the HTTP module for this, because it does all of the parsing for you.

Resources