Code Monkey home page Code Monkey logo

union's Introduction

Framework components for node.js and the browser

Example HTTP Server:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http);

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Example HTTPS Server:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http, {
  https: {
    cert: 'path/to/cert.pem',
    key: 'path/to/key.pem',
    ca: 'path/to/ca.pem'
  }
});

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Example CLI Application:

// example.js

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: __dirname,
  usage: [
    'This is a basic flatiron cli application example!',
    '',
    'hello - say hello to somebody.'
  ]
});

app.cmd('hello', function () {
  app.prompt.get('name', function (err, result) {
    app.log.info('hello '+result.name+'!');
  })
})

app.start();

Run It:

% node example.js hello
prompt: name: world
info:   hello world!

Installation

Installing NPM (Node Package Manager)

  curl http://npmjs.org/install.sh | sh

Installing Flatiron

  [sudo] npm install flatiron

Installing Union (Required for flatiron.plugins.http)

  npm install union

Usage:

Start With flatiron.app:

flatiron.app is a broadway injection container. To be brief, what it does is allow plugins to modify the app object directly:

var flatiron = require('flatiron'),
    app = flatiron.app;

var hello = {
  attach: function (options) {
    this.hello = options.message || 'Why hello!';
  }
};

app.use(hello, {
  message: "Hi! How are you?"
});

// Will print, "Hi! How are you?"
console.log(app.hello);

Virtually all additional functionality in flatiron comes from broadway plugins, such as flatiron.plugins.http and flatiron.plugins.cli.

app.config

flatiron.app comes with a config plugin pre-loaded, which adds configuration management courtesy nconf. app.config has the same api as the nconf object.

The literal store is configured by default. If you want to use different stores you can easily attach them to the app.config instance.

// add the `env` store to the config
app.config.use('env');

// add the `file` store the the config
app.config.use('file', { file: 'path/to/config.json' });

// or using an alternate syntax
app.config.env().file({ file: 'path/to/config.json' });

// and removing stores
app.config.remove('literal');

app.log

flatiron.app will also load a log plugin during the init phase, which attaches a winston container to app.log. This logger is configured by combining the app.options.log property with the configuration retrieved from app.config.get('log').

Create An HTTP Server with flatiron.plugins.http(options):

This plugin adds http serving functionality to your flatiron app by attaching the following properties and methods:

Define Routes with app.router:

This is a director router configured to route http requests after the middlewares in app.http.before are applied. Example routes include:

// GET /
app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

// POST to /
app.router.post('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.write('Hey, you posted some cool data!\n');
  this.res.end(util.inspect(this.req.body, true, 2, true) + '\n');
});

// Parameterized routes
app.router.get('/sandwich/:type', function (type) {
  if (~['bacon', 'burger'].indexOf(type)) {
    this.res.writeHead(200, { 'Content-Type': 'text/plain' });
    this.res.end('Serving ' + type + ' sandwich!\n');
  }
  else {
    this.res.writeHead(404, { 'Content-Type': 'text/plain' });
    this.res.end('No such sandwich, sorry!\n');
  }
});

app.router can also route against regular expressions and more! To learn more about director's advanced functionality, visit director's project page.

Access The Server with app.server:

This is a union middleware kernel.

Modify the Server Options with app.http:

This object contains options that are passed to the union server, including app.http.before, app.http.after and app.http.headers.

These properties may be set by passing them through as options:

app.use(flatiron.plugins.http, {
  before: [],
  after: []
});

You can read more about these options on the union project page.

Start The Server with app.start(port, <host>, <callback(err)>)

This method will both call app.init (which will call any asynchronous initialization steps on loaded plugins) and start the http server with the given arguments. For example, the following will start your flatiron http server on port 8080:

app.start(8080);

Create a CLI Application with flatiron.plugins.cli(options)

This plugin turns your app into a cli application framework. For example, [jitsu] (https://github.com/nodejitsu/jitsu) uses flatiron and the cli plugin.

Valid options include:

{
  "argvOptions": {}, // A configuration hash passed to the cli argv parser.
  "usage": [ "foo", "bar" ], // A message to show for cli usage. Joins arrays with `\n`.
  "dir": require('path').join(__dirname, 'lib', 'commands'), // A directory with commands to lazy-load
  "notFoundUsage": false // Disable help messages when command not found
}

Add lazy-loaded CLI commands with options.dir and app.commands:

Flatiron CLI will automatically lazy-load modules defining commands in the directory specified by options.dir. For example:

// example2.js
var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: path.join(__dirname, 'cmds')
});

app.start();
// cmd/highfive.js
var highfive = module.exports = function highfive (person, cb) {
  this.log.info('High five to ' + person + '!');
  cb(null);
};

In the command, you expose a function of arguments and a callback. this is set to app, and the routing is taken care of automatically.

Here it is in action:

% node example2.js highfive Flatiron 
info:   High five to Flatiron!

You can also define these commands by adding them directly to app.commands yourself:

// example2b.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli);

app.commands.highfive = function (person, cb) {
  this.log.info('High five to ' + person + '!');
  cb(null);
};

app.start();
% node example2b.js highfive Flatiron 
info:   High five to Flatiron!

Callback will always be the last argument provided to a function assigned to command

app.commands.highfive = function (person, cb) {
  this.log.info('High five to ' + person + '!');
  console.log(arguments);
}
% node example2b.js highfive Flatiron lol haha
info:    High five to Flatiron!
{
  '0': 'Flatiron',
  '1': 'lol',
  '2': 'haha',
  '3': [Function]
}

Define Ad-Hoc Commands With app.cmd(path, handler):

This adds the cli routing path path to the app's CLI router, using the director route handler handler, aliasing app.router.on. cmd routes are defined the same way as http routes, except that it uses (a space) for a delimiter instead of /.

For example:

// example.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    'usage: node test.js hello <person>',
    '',
    '  This will print "hello <person>"'
  ]
});

app.cmd('hello :person', function (person) {
  app.log.info('hello ' + person + '!');
});

app.start()

When you run this program correctly, it will say hello:

% node example.js hello person
info:   hello person!

If not, you get a friendly usage message:

% node test.js hello
help:   usage: node test.js hello <person>
help:
help:     This will print "hello <person>"

Check CLI Arguments with app.argv:

Once your app is started, app.argv will contain the optimist-parsed argv options hash, ready to go!

Here's an example:

// example3.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli);

app.start();

app.log.info(JSON.stringify(app.argv));

This prints:

% node example3.js
info:    {"_":[], "$0": "node ./example3.js"}

Awesome!

Add a Default Help Command with options.usage:

When attaching the CLI plugin, just specify options.usage to get a friendly default message for when there aren't any matching routes:

// example4.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    'Welcome to my app!',
    'Your command didn\'t do anything.',
    'This is expected.'
  ]
});

app.start();
% node example4.js 
help:   Welcome to my app!
help:   Your command didn't do anything.
help:   This is expected.

Start The Application with app.start(callback):

As seen in these examples, starting your app is as easy as app.start! this method takes a callback, which is called when an app.command completes. Here's a complete example demonstrating this behavior and how it integrates with options.usage:

// example5.js
var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    '`node example5.js error`: Throws an error.',
    '`node example5.js friendly`: Does not throw an error.'
  ]
});

app.commands.error = function (cb) {
  cb(new Error('I\'m an error!'));
};

app.commands.friendly = function (cb) {
  cb(null);
}

app.start(function (err) {
  if (err) {
    app.log.error(err.message || 'You didn\'t call any commands!');
    app.log.warn('NOT OK.');
    return process.exit(1);
  }
  app.log.info('OK.');
});

Here's how our app behaves:

% node example5.js friendly
info:   OK.

% node example5.js error
error:  I'm an error!
warn:   NOT OK.

% node example5.js
help:   `node example2b.js error`: Throws an error.
help:   `node example2b.js friendly`: Does not throw an error.
error:  You didn't call any commands!
warn:   NOT OK.

Read More About Flatiron!

Articles

Sub-Projects

Tests

Tests are written in vows:

  $ npm test

License: MIT

union's People

Contributors

3rd-eden avatar bbtx0 avatar buptsb avatar coderarity avatar dominictarr avatar dscape avatar eschmitt avatar fent avatar framp avatar indexzero avatar jcrugzz avatar jfhbrook avatar marak avatar mmalecki avatar pdehaan avatar pkrefta avatar pksunkara avatar tellnes avatar thornjad avatar xmader avatar yawnt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

union's Issues

setEncoding is not defined

We need this for a variety of reasons. Currently, without it using connect middleware like bodyParser.js causes incorrect parsing of the POST body.

Add SPDX License Identifier to package.json

Hi there!

We are currently adapting a package approval workflow, where packages are approved or blocked based on certain criteria. One very important criterion is the package's license. There is a list of approved licenses (like MIT, Apache, ...) and a list of licenses that can not be used (like GPL).

Although your package seems to be under MIT license, it's hard to auto-approve them, because they don't use an SPDX tag (https://spdx.github.io/spdx-spec/v2-draft/SPDX-license-list/). As a result, the license does not show up in the package's metadata (compare e.g. info section of https://www.npmjs.com/package/union with https://www.npmjs.com/package/@angular/core, where the latter clearly states the package's license, while yours does not).

Would you consider using an SPDX license expression? Basically, all that is needed is a license entry in the package.json file.
See https://docs.npmjs.com/cli/v10/configuring-npm/package-json#license for reference.
In fact, it seems that there is actually an open pull request for this already.

Additional LICENSE files or license infos in README files can remain as they are (as long as they don't contradict the content of the "license" entry).

This would be a huge help for us, because without license information within packages' metadata we have to manually check and approve every single version of every package.

Header test hangs

Running npm test or directly running node test/header-test.js hangs. This occurs when running on Linux, and (as reported by @BigBlueHat in #61 (comment)) on bash on Windows in mingw, but interestingly does not hang in cmd.

Here's the output I get on Linux, even after left running for 10 minutes:

$ npm test

> [email protected] test /home/jade/src/thornjad/union
> vows test/*-test.js --spec -i


  โ™ข union/after

  When using union a union server with after middleware
    โœ“ should preserve the request until the last call

  โ™ข union/body-parser

  When using union with connect body parsing via urlencoded() or json() a request to /
    โœ“ should respond with a body-decoded object

  โ™ข union/double-write

  When using union an http server which attempts to write to the response twice a GET request to /foo
    โœ“ it should respond with { 'hello': 'world' }
    โœ“ it should not write to the response twice
  When the tests are over
    โœ“ the server should close

  โ™ข union/ecstatic

  When using union with ecstatic a request to /404.txt (which does not exist)
    โœ“ should respond with 404 status code
  When using union with ecstatic a request to /some-file.txt
    โœ“ should respond with hello world

  โ™ข union/header


Can't pipe

When used like that:

var fs = require('fs'),
    union = require('union');

union.createServer({
  before: [
    function (req, res, next) {
      var writeStream = fs.createWriteStream('req');
      req.pipe(writeStream);

      writeStream.on('close', function () {
        res.writeHead(200);
        res.end('Wrote to a stream\n');
      });
    }
  ]
}).listen(9000);

file req gets created but no data is found there (empty file) after I POST something to localhost:9000. Can someone confirm it should work so that I can write a test case?

It happens on current master - 3eeeef8.

Connect compatibility issue (bodyParser)

Start a fresh project; install latest connect and union.

index.js

var fs = require('fs'),
    union = require('union'),
    connect = require('connect');

var server = union.createServer({
  before: [
    connect.bodyParser(),
    function (req, res) {
        res.writeHead(200, { 'Content-Type': 'text/html' })
        res.end('<form action="" method="post"><input name=t><input type=submit></form>');
    }
  ]
});

server.listen(9090);

Error when form is submitted:

_stream_readable.js:196
this._readableState.decoder = new StringDecoder(enc);
^
TypeError: Cannot set property 'decoder' of undefined
at Readable.setEncoding (_stream_readable.js:196:31)
at /test/node_modules/connect/lib/middleware/urlencoded.js:63:11
at noop (/test/node_modules/connect/lib/middleware/urlencoded.js:22:3)
at urlencoded (/test/node_modules/connect/lib/middleware/urlencoded.js:60:5)
at /test/node_modules/connect/lib/middleware/bodyParser.js:55:7
at json (/test/node_modules/connect/lib/middleware/json.js:56:55)
at Array.bodyParser [as 0] (/test/node_modules/connect/lib/middleware/bodyParser.js:53:5)
at dispatch (/test/node_modules/union/lib/routing-stream.js:110:21)
at RoutingStream.route (/test/node_modules/union/lib/routing-stream.js:121:5)
at g (events.js:175:14)

EDIT: tested with node v0.10.6, union v0.3.7, connect v2.7.11

bizarre post parsing with latest flatiron

Relevant code:

  app.router.post(options.route, function sendgridPostHandler () {
    var json = require('util').inspect(this.req.body);

    app.log.info('this.req.body: ' + json);
    this.res.end('received');
  });

Relevant curl (problem isn't here):

% curl -X POST -d 'test' localhost:8080/mailjitsu.js
received%   

Relevant logs:

info: Server started on :8080
info: [POST] /mailjitsu.js
info: this.req.body: { test: '' }

{ test: "" } ? Where did that come from? My guess is here, but I'm not sure.

I'm going to bed for now. Insights would be great.

Using after filters

I have the following code which I think is needed for using after streams.

this.http.server = union.createServer({
    before: [
        function (req, res) {
            var found = self.http.router.dispatch(req, res);
            if (!found) {
                res.emit('next');
            }
        }
    ],
    after: [
        new union.ResponseStream()
    ]
});

But when I start this application, I get the following error:
warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

Can you please provide a better/any example for using after streams?

SPDY support

Hi guys,

I've started working on SPDY implementation for flatiron flatiron/flatiron#32. Adding SPDY requires some changes in union too. Can I issue pull request for this ?

Connect 2.0.3 bodyParser middleware issue

var flatiron = require('flatiron'),
    connect = require('connect'),
    app = flatiron.app;

app.use(flatiron.plugins.http, {
  before: [
    connect.bodyParser(),
    function(req, res){}
  ]
});

app.start(9090);

Pretty basic setup, now try posting some data:

curl -d "foo=bar" http://localhost:9090

The server crashes with this error message:

TypeError: Object [object Object] has no method 'setEncoding'

It seems that the standard node http request method setEncoding isn't present in the req object that is passed to middleware.

I give up for now... :)

Cheers,

everyauth middleware problem

Hi,

Can anyone help me with this:
I am trying to integrate everyauth with union server. I call the middleware on
before:[
everyauth.middleware(),
........ router.dispatch(...)
]

When I do this, the server blocks and doent return or do anything! Am I doing it wrong ?

example and tests break on 0.4.12

Running the example gives:

substack : examples $ node simple.js 
union with director running on 8080

/home/substack/projects/union/node_modules/director/lib/director/router.js:402
      match   = path.match(new RegExp('^' + current));
                           ^
SyntaxError: Invalid regular expression: /^/\/: \ at end of pattern
    at new RegExp (unknown source)
    at [object Object].traverse (/home/substack/projects/union/node_modules/director/lib/director/router.js:402:28)
    at [object Object].dispatch (/home/substack/projects/union/node_modules/director/lib/director/http/index.js:62:18)
    at Array.1 (/home/substack/projects/union/examples/simple.js:12:26)
    at dispatch (/home/substack/projects/union/lib/routing-stream.js:100:20)
    at [object Object].<anonymous> (native)
    at [object Object].g (events.js:143:14)
    at [object Object].emit (events.js:61:17)
    at /home/substack/projects/union/lib/routing-stream.js:96:21
    at Array.favicon [as 0] (/home/substack/projects/union/examples/middleware/favicon.js:93:7)
substack : examples $ 

and since the test uses the example file, the test also fails.

Simple case from Readme.md

I don't know if this is planned but simple case form Readme.md could be a little confusing for newbie users because it requires unknown module ./middleware/favicon. I'm aware that this require is from local filesystem and it should be implemented (and it is in exmples folder) but IMHO simple cases should be working out of the box with simple copy-paste.

What do you think guys ?

Piping response fails

Run the example, request locahost:8080. You'll get this:


union with sugarskull running on 8080

events.js:148
    throw new Error('.once only takes instances of Function');
          ^
Error: .once only takes instances of Function
    at [object Object].once (events.js:148:11)
    at new <anonymous> (/Users/maciej/Programowanie/JavaScript/union/lib/response-stream.js:23:8)
    at new <anonymous> (/Users/maciej/Programowanie/JavaScript/union/lib/routing-stream.js:25:17)
    at Server.<anonymous> (/Users/maciej/Programowanie/JavaScript/union/lib/core.js:26:25)
    at Server.emit (events.js:70:17)
    at HTTPParser.onIncoming (http.js:1479:12)
    at HTTPParser.onHeadersComplete (http.js:102:31)
    at Socket.ondata (http.js:1375:22)
    at TCP.onread (net.js:334:27)

Unknown license vulnerability

Snyk was not able to detect a license for this package. This could occur from a package file that lacks a license definition or might be having incorrect format.

connect.session doesn't work for connect > 2.3.5

It dies with

/home/kenji/nodejs/union/node_modules/connect/lib/middleware/session.js:213
    if (0 != req.originalUrl.indexOf(cookie.path || '/')) return next();
                             ^
TypeError: Cannot call method 'indexOf' of undefined
    at Array.session [as 4] (/home/kenji/nodejs/union/node_modules/connect/lib/middleware/session.js:213:30)
    at dispatch (/home/kenji/nodejs/union/node_modules/union/lib/routing-stream.js:110:21)
    at g (events.js:185:14)
    at EventEmitter.emit (events.js:85:17)
    at RoutingStream.route (/home/kenji/nodejs/union/node_modules/union/lib/routing-stream.js:114:23)
    at Array.cookieParser [as 3] (/home/kenji/nodejs/union/node_modules/connect/lib/middleware/cookieParser.js:60:5)
    at dispatch (/home/kenji/nodejs/union/node_modules/union/lib/routing-stream.js:110:21)
    at g (events.js:185:14)
    at EventEmitter.emit (events.js:85:17)
    at RoutingStream.route (/home/kenji/nodejs/union/node_modules/union/lib/routing-stream.js:114:23)

Minimal example to reproduce:

var connect = require('connect')
  , union = require('union');

var server = union.createServer({
  buffer: false,
  before: [
    connect.cookieParser('my secret here'),
    connect.session()
  ]
}).listen(3000);

Not compatible with connect-static-file middleware

connect-static-file middleware does not work with union. With connect, it works as expected:

var connect = require('connect')
  , http = require('http')
  , staticFile = require('connect-static-file');

var app = connect()
  .use(staticFile('index.js'));

http.createServer(app).listen(3000);

With union, the browser never gets a response (loading and loading and loading)...:

var connect = require('connect')
  , union = require('union')
  , staticFile = require('connect-static-file');

var server = union.createServer({
  buffer: false,
  before: [
    staticFile('index.js')
  ]
}).listen(3000);

connect-static-file uses send under the hood. Tested with:

"connect": "^3.6.2",
"connect-static-file": "^1.2.0",
"union": "^0.4.6"
node v6.10.3

connect session not working

there's still issue with connect session middleware and union:

-union: 0.1.7
-flatiron: 0.1.11
-connect: 2.0.0alpha1

As mentioned, connect patch ServerResponse prototype to support event "header". (connect/lib/patch.js)
On session middleware, connect expect the response parameter to be a http.ServerResponse and it listens to "header" event to write cookie header.
(line 221 on connect/lib/middleware/session.js)

    // set-cookie
    res.on('header', function(){
      if (!req.session) return;
      var cookie = req.session.cookie
        , proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
        , tls = req.connection.encrypted || (trustProxy && 'https' == proto)
        , secured = cookie.secure && tls;

      // browser-session cookies only set-cookie once
      if (null == cookie.expires && !sessionIsNew) return;

      // only send secure cookies via https
      if (cookie.secure && !secured) return debug('not secured');

      debug('set %s to %s', key, req.sessionID);
      res.setHeader('Set-Cookie', cookie.serialize(key, req.sessionID));
    });

As response object forwarded by union to connect is a ResponseStream object, "header" event is never emit.

row

    // set-cookie
    res.on('header', function(){

should be

    // set-cookie
    res.response.on('header', function(){

no idea of how to work around this issue

Not compatible with all connect middleware

Deps:
[email protected]
[email protected]

Sessions are non-compatible, consider this basic application:

var flatiron = require('flatiron'),
    path = require('path'),
    app = flatiron.app,
    connect = require('connect');

app.use(flatiron.plugins.http, {
  before: [
        connect.cookieParser(),
    connect.session({secret: "test"}),
   ]
});

if (require.main === module) {
  app.init(function () {  
    app.start(8080);
  });
}

So navigating to http://localhost:8080 I would presume would not cause the app to error out. Here is the stack:

"stack": [
    "TypeError: Object [object Object] has no method '_implicitHeader'",
    "    at [object Object].<anonymous> (/node_modules/connect/lib/middleware/session.js:279:31)",
    "    at Object.error (/node_modules/union/lib/core.js:58:14)",
    "    at [object Object].dispatch (/node_modules/flatiron/node_modules/director/lib/director/http/index.js:87:16)",
    "    at Array.2 (/node_modules/flatiron/lib/flatiron/plugins/http.js:72:25)",
    "    at dispatch (/node_modules/union/lib/routing-stream.js:105:20)",
    "    at [object Object].<anonymous> (native)",
    "    at [object Object].g (events.js:156:14)",
    "    at [object Object].emit (events.js:64:17)",
    "    at /node_modules/union/lib/routing-stream.js:101:21",
    "    at /node_modules/connect/lib/middleware/session.js:323:9"
  ],
  "level": "error",
  "message": "uncaughtException"

[email protected] cannot be installed without package-lock.json

$ npm init -y
$ npm install union
npm ERR! code 1
npm ERR! path /home/ANT.AMAZON.COM/calebev/tmp/node_modules/union
npm ERR! command failed
npm ERR! command sh -c npx npm-force-resolutions
npm ERR! npm WARN exec The following package was not found and will be installed: [email protected]
npm ERR! Error: ENOENT: no such file or directory, open './package-lock.json'

This is a bug in npm-force-resolutions, but the issues have been open for a while and the last commit was 3 years ago so I don't think it will be fixed.

union could use npm 8's overrides, or use force-resolutions, or npm-force-resolutions || true.

rogeriochaves/npm-force-resolutions#10
rogeriochaves/npm-force-resolutions#36
rogeriochaves/npm-force-resolutions#66

request/response objects do not implement the entire core req/res API

I tried to use connect's static provider, which should've Just Worked. However, it seems that the req and res objects between connect/express and flatiron are not 100% compatible.

Here's a reproducing test program:

var union = require("union"),
    express = require("express"),
    static = express.static(__dirname + '/static');

union.createServer({
  before: [
    static
  ]
}).listen(8080);

express.createServer(static).listen(8081);

console.log("union: localhost:8080");
console.log("express: localhost:8081");

This program works fine for the express server, but for the union server:

josh@onix:/tmp/express-test$ node test.js 
union: localhost:8080
express: localhost:8081

/tmp/express-test/node_modules/express/node_modules/connect/lib/middleware/static.js:162
    if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()
             ^
TypeError: Object [object Object] has no method 'getHeader'
    at /tmp/express-test/node_modules/express/node_modules/connect/lib/middleware/static.js:162:14
josh@onix:/tmp/express-test$ 

Odd issues with response stream missing a bunch of stuff

So, I've been trying to get a static middleware for union (and express) running, and I got a bunch of nice features implemented by @substack but getting it to work with union is being painful.

Running the example with the gh-4 branch (which tries to implement getHeader & friends) and trying to get /hello.txt gets you this:

josh@onix:~/dev/ecstatic$ node example/union.js 
Listening on :8080

/home/josh/dev/union/lib/http-stream.js:40
    this.query = ~source.url.indexOf('?')
                             ^
TypeError: Cannot call method 'indexOf' of undefined
    at [object Object].pipeState (/home/josh/dev/union/lib/http-stream.js:40:30)
    at [object Object].emit (events.js:81:20)
    at [object Object].pipe (stream.js:159:8)
    at /home/josh/dev/ecstatic/ecstatic.js:52:11
[1]+  Done                    gedit ecstatic.js
josh@onix:~/dev/ecstatic$ 

So, source.url is missing. Okay, I can circumvent this. But, when I do, it seems the problem's deeper:

josh@onix:~/dev/ecstatic$ node example/union.js 
Listening on :8080
Cannot call method 'indexOf' of undefined

events.js:143
    listener.apply(this, arguments);
             ^
TypeError: Cannot call method 'apply' of undefined
    at [object Object].g (events.js:143:14)
    at [object Object].emit (events.js:81:20)
    at [object Object].pipe (stream.js:159:8)
    at /home/josh/dev/ecstatic/ecstatic.js:52:11
josh@onix:~/dev/ecstatic$ 

This is what ecstatic is doing with the response around that time:

        res.setHeader('content-type', mime.lookup(file));
        var s = fs.createReadStream(file);
        s.pipe(res);
        s.on('error', function (err) {
          res.statusCode = 500;
          if (res.writable) res.end(err && err.stack || err.toString());
        });

and the error seems to occur on s.pipe(res).

I'd fix this myself but I'm not really sure where to look.

.

.

Most basic Union server takes 200ms to respond, compared to 2ms for Express?

I created the following simple Union server, and it takes 200ms to respond with the "not found" error message.

var union = require('union');

var server = module.exports = union.createServer({

    buffer: false

});

The comparable server with Express, and even more so the bare http server, only takes 1-3ms to respond with the same message. Express is just what I used as a comparison because I knew how to quickly write a similar test.

I'm running this server on a development machine on my LAN. The machine has an i7 processor, and SSD drive, so it's most definitely not something there. It's not a Raspberry Pi with an SD card or anything.

Any ideas why this might be so slow? I can't imagine the 200ms is justified somehow. I have other web apps that do template rendering and database queries in less than that amount of time. That's why I decided to go ahead and make this ticket. Thanks.

DeprecationWarning: OutgoingMessage.prototype._headers is deprecated

% node --trace-deprecation /usr/local/bin/http-server
Starting up http-server, serving ./public
Available on:
  http://127.0.0.1:8080
  http://10.2.198.96:8080
Hit CTRL-C to stop the server
[2020-11-11T03:40:13.184Z]  "GET /" "Mozilla/5.0"
(node:13803) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
    at new module.exports (/usr/local/lib/node_modules/http-server/node_modules/union/lib/response-stream.js:50:60)
    at new module.exports (/usr/local/lib/node_modules/http-server/node_modules/union/lib/routing-stream.js:30:17)
    at Server.requestHandler (/usr/local/lib/node_modules/http-server/node_modules/union/lib/core.js:27:25)
    at Server.emit (node:events:327:20)
    at parserOnIncoming (node:_http_server:919:12)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:126:17)

this._headers = this.response._headers = this.response._headers || {};

See also #64 http-party/http-server#799

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.