Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle entity too large and devMode #75

Merged
merged 6 commits into from
Jun 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"plugins": ["transform-flow-comments"]
"plugins": ["transform-flow-comments", "transform-object-rest-spread"]
}
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 0.13.16
* Explicitly handle too large kraken notification payloads
* Adds devMode utility
* Turn on flow in index.js files

# 0.13.15
* Bump hull-client version to 1.2.2
* Adds support for Account anonymous_id claim
Expand Down
20 changes: 14 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hull",
"version": "0.13.15",
"version": "0.13.16",
"description": "A Node.js client for hull.io",
"main": "lib",
"repository": {
Expand Down Expand Up @@ -35,6 +35,7 @@
"dependencies": {
"JSONStream": "^1.1.2",
"aws-sdk": "^2.81.0",
"babel-polyfill": "^6.26.0",
"basic-auth": "^1.1.0",
"batch-stream": "^0.1.3",
"bluebird": "^3.4.7",
Expand All @@ -54,26 +55,32 @@
"kue": "^0.11.5",
"kue-ui": "^0.1.0",
"lodash": "^4.17.5",
"newrelic": "^2.4.1",
"newrelic": "^4.1.4",
"passport": "^0.3.2",
"progress-bar-webpack-plugin": "^1.11.0",
"promise-streams": "^1.0.1",
"raven": "^2.4.2",
"raw-body": "^2.1.7",
"react-hot-loader": "^4.2.0",
"request": "^2.72.0",
"sns-validator": "^0.3.0",
"sqs-consumer": "^3.6.1",
"supply": "0.0.4",
"urijs": "^1.18.7"
"urijs": "^1.18.7",
"webpack": "^3.12.0",
"webpack-dev-middleware": "^2.0.6",
"webpack-hot-middleware": "^2.22.2"
},
"peerDependencies": {
"express": "^4.16.2",
"newrelic": "^2.4.1"
"express": "^4.16.3",
"newrelic": "^4.1.4"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-cli": "^6.24.1",
"babel-eslint": "^7.1.1",
"babel-plugin-transform-flow-comments": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-register": "^6.9.0",
"chai": "^3.5.0",
"chai-http": "^3.0.0",
Expand All @@ -90,12 +97,13 @@
"mkdirp": "^0.5.1",
"mocha": "^3.0.0",
"nock": "^9.2.3",
"node-mocks-http": "^1.6.1",
"node-mocks-http": "^1.7.0",
"nyc": "^11.0.3",
"rimraf": "^2.6.0",
"sinon": "^2.2.0",
"sinon-chai": "^2.10.0",
"superagent": "^3.8.2",
"supertest": "^3.1.0",
"updtr": "^1.0.0"
},
"nodeBoilerplateOptions": {
Expand Down
1 change: 1 addition & 0 deletions src/errors/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @flow
/* eslint-disable global-require */

/**
Expand Down
59 changes: 59 additions & 0 deletions src/utils/dev-mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// @flow
import type { $Application } from "express";

const _ = require("lodash");
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpackHotMiddleware = require("webpack-hot-middleware");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");

function devMode(app: $Application, config: Object) {
const entry = _.reduce(
config.entry,
(m: Object, v, k: string) => {
m[k] = [
require.resolve("babel-polyfill"),
require.resolve("react-hot-loader/patch"),
require.resolve("webpack-hot-middleware/client"),
v
];
return m;
},
{}
);

const plugins = [
new webpack.HotModuleReplacementPlugin(),
...config.plugins,
new webpack.NamedModulesPlugin(),
new ProgressBarPlugin({ clear: false }),
new webpack.NoEmitOnErrorsPlugin()
];

const compiler = webpack({ ...config, entry, plugins });

app.use(
webpackDevMiddleware(compiler, {
hot: true,
quiet: false,
overlay: false,
noInfo: false,
lazy: false,
clientLogLevel: "none",
watchContentBase: true,
stats: { colors: true },
watchOptions: {
ignored: /node_modules/
},
historyApiFallback: {
disableDotRule: true
},

headers: { "Access-Control-Allow-Origin": "http://localhost" },
publicPath: config.output.publicPath
})
);
app.use(webpackHotMiddleware(compiler));
}

module.exports = devMode;
7 changes: 5 additions & 2 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @flow
/**
* General utilities
* @namespace Utils
Expand All @@ -24,5 +25,7 @@ module.exports.SmartNotifierResponse = require("./smart-notifier-response");
module.exports.PromiseReuser = require("./promise-reuser");

module.exports.superagentUrlTemplatePlugin = require("./superagent-url-template-plugin");
module.exports.superagentInstrumentationPlugin = require("././superagent-intrumentation-plugin.js");
module.exports.superagentErrorPlugin = require("././superagent-error-plugin.js");
module.exports.superagentInstrumentationPlugin = require("./superagent-intrumentation-plugin.js");
module.exports.superagentErrorPlugin = require("./superagent-error-plugin.js");

module.exports.devMode = require("./dev-mode");
10 changes: 9 additions & 1 deletion src/utils/smart-notifier-middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ module.exports = function smartNotifierMiddlewareFactory({ skipSignatureValidati
}
}

return bodyParser.json({ limit: "10mb" })(req, res, () => {
return bodyParser.json({ limit: "10mb" })(req, res, (err) => {
if (err !== undefined && err.type === "entity.too.large") {
Client.logger.error("connector.smartNotifierHandler.error", { error: err.toString() });
return next(new SmartNotifierError("ENTITY_TOO_LARGE", "Payload size bigger than 10mb", err.statusCode, {
type: "retry",
size: 1
}));
}

Client.logger.debug("connector.smartNotifierHandler", _.pick(req.body, "channel", "notification_id"));

if (!smartNotifierValidator.validatePayload()) {
Expand Down
42 changes: 40 additions & 2 deletions test/unit/utils/smart-notifier-middleware-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* global describe, it */
const { expect, should } = require("chai");
const sinon = require("sinon");
const { expect } = require("chai");
const http = require("http");
const request = require("supertest");

const smartNotifierMiddleware = require("../../../src/utils/smart-notifier-middleware");

Expand All @@ -10,4 +11,41 @@ describe("SmartNotifierMiddleware", () => {
const testInstance = new smartNotifierMiddleware({});
expect(typeof testInstance).to.equal("function");
});

it("should handle notifications exceeding the json size limit", (done) => {
const testInstance = new smartNotifierMiddleware({ skipSignatureValidation: true });
const server = http.createServer((req) => {
testInstance(req, {}, (err) => {
expect(err.code).to.equal("ENTITY_TOO_LARGE");
expect(err.statusCode).to.equal(413);
expect(err.flowControl).to.eql({
type: "retry",
size: 1
});
done();
});
});
request(server)
.post("/")
.set("Content-Type", "application/json")
.set({
"content-type": "application/json",
"x-hull-smart-notifier": "yes",
"x-hull-smart-notifier-signature": "singature",
"x-hull-smart-notifier-signature-version": "v1",
"x-hull-smart-notifier-signature-public-key-url": "url"
})
.send({
configuration: {
id: "12312312312"
},
connector: {},
messages: [{
user: {
super_long_trait: String(".").repeat(10485760) // 10mb string
}
}]
})
.end(() => {});
});
});