1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | "use strict";
|
15 |
|
16 | var fluid = require("infusion"),
|
17 | kettle = fluid.registerNamespace("kettle");
|
18 |
|
19 |
|
20 | fluid.require("body-parser", require, "kettle.npm.bodyParser");
|
21 | fluid.require("cookie-parser", require, "kettle.npm.cookieParser");
|
22 | fluid.require("serve-static", require, "kettle.npm.serveStatic");
|
23 |
|
24 | fluid.defaults("kettle.middlewareHolder", {
|
25 | gradeNames: "fluid.component"
|
26 | });
|
27 |
|
28 | fluid.defaults("kettle.standardMiddleware", {
|
29 | gradeNames: "kettle.middlewareHolder",
|
30 | components: {
|
31 | urlencoded: {
|
32 | type: "kettle.middleware.urlencoded"
|
33 | },
|
34 | json: {
|
35 | type: "kettle.middleware.json"
|
36 | },
|
37 | CORS: {
|
38 | type: "kettle.middleware.CORS"
|
39 | },
|
40 | "null": {
|
41 | type: "kettle.middleware.null"
|
42 | },
|
43 | mismatch: {
|
44 | type: "kettle.middleware.mismatch"
|
45 | }
|
46 | }
|
47 | });
|
48 |
|
49 | fluid.registerNamespace("kettle.middleware");
|
50 |
|
51 | kettle.middleware.resolveSequence = function (that, name, middlewareSpec) {
|
52 | var middlewares = fluid.hashToArray(middlewareSpec, "namespace", function (newEl, el) {
|
53 | newEl.component = fluid.expandOptions(el.middleware, that);
|
54 | if (!fluid.isComponent(newEl.component) || !fluid.componentHasGrade(newEl.component, "kettle.middleware")) {
|
55 | fluid.fail("Couldn't resolve reference " + el.middleware + " from member \"middleware\" of record ", el, " to a middleware component for a " + name + ": got ", newEl.component);
|
56 | }
|
57 | newEl.priority = fluid.parsePriority(el.priority, 0, false, name);
|
58 | });
|
59 | fluid.sortByPriority(middlewares);
|
60 | return middlewares;
|
61 | };
|
62 |
|
63 | kettle.middleware.getHandlerSequence = function (that, memberName) {
|
64 | var resolved = kettle.middleware.resolveSequence(that, that.typeName + " " + memberName + " entry", that.options[memberName]);
|
65 | var sequence = fluid.getMembers(resolved, "component.handle");
|
66 | return sequence;
|
67 | };
|
68 |
|
69 |
|
70 | fluid.defaults("kettle.middleware", {
|
71 | gradeNames: ["fluid.component"],
|
72 | invokers: {
|
73 | handle: {
|
74 | funcName: "fluid.notImplemented"
|
75 | }
|
76 | }
|
77 | });
|
78 |
|
79 |
|
80 | fluid.defaults("kettle.plainMiddleware", {
|
81 | gradeNames: "kettle.middleware",
|
82 | asyncMiddleware: false,
|
83 | invokers: {
|
84 | handle: {
|
85 | funcName: "kettle.plainMiddleware.resolve",
|
86 | args: ["{that}", "{arguments}.0", "{plainMiddleware}.options.asyncMiddleware"]
|
87 | }
|
88 | }
|
89 | });
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 | fluid.defaults("kettle.plainAsyncMiddleware", {
|
96 | gradeNames: "kettle.plainMiddleware",
|
97 | asyncMiddleware: true
|
98 | });
|
99 |
|
100 |
|
101 | kettle.middleware.nullHandler = function () {
|
102 | return fluid.promise().resolve();
|
103 | };
|
104 |
|
105 | fluid.defaults("kettle.middleware.null", {
|
106 | gradeNames: "kettle.plainMiddleware",
|
107 | invokers: {
|
108 | handle: {
|
109 | funcName: "kettle.middleware.nullHandler"
|
110 | }
|
111 | }
|
112 | });
|
113 |
|
114 | kettle.middleware.toPromise = function (middleware, request, async) {
|
115 | var togo = fluid.promise();
|
116 | if (async) {
|
117 | kettle.request.clear();
|
118 | }
|
119 | middleware(request.req, request.res, function (err) {
|
120 | if (async) {
|
121 | kettle.markActiveRequest(request);
|
122 | }
|
123 | err ? togo.reject(err) : togo.resolve();
|
124 | });
|
125 | return togo;
|
126 | };
|
127 |
|
128 | kettle.plainMiddleware.resolve = function (that, request, async) {
|
129 | var middleware = that.options.middleware;
|
130 | if (typeof(middleware) !== "function") {
|
131 | fluid.fail("Middleware component ", that, " with type " + that.typeName + " is improperly configured - an option named \"middleware\" of function type is required - got ", middleware);
|
132 | }
|
133 | return kettle.middleware.toPromise(middleware, request, async);
|
134 | };
|
135 |
|
136 | fluid.defaults("kettle.middleware.json", {
|
137 | gradeNames: ["kettle.plainMiddleware"],
|
138 | middlewareOptions: {},
|
139 | middleware: "@expand:kettle.npm.bodyParser.json({that}.options.middlewareOptions)"
|
140 | });
|
141 |
|
142 | fluid.defaults("kettle.middleware.urlencoded", {
|
143 | gradeNames: ["kettle.plainMiddleware"],
|
144 | middlewareOptions: {
|
145 | extended: true
|
146 | },
|
147 | middleware: "@expand:kettle.npm.bodyParser.urlencoded({that}.options.middlewareOptions)"
|
148 | });
|
149 |
|
150 | fluid.defaults("kettle.middleware.CORS", {
|
151 | gradeNames: ["kettle.middleware"],
|
152 | allowMethods: "GET",
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | origin: "*",
|
158 |
|
159 |
|
160 | credentials: true,
|
161 | invokers: {
|
162 | handle: {
|
163 | funcName: "kettle.middleware.CORSHandle",
|
164 | args: [
|
165 | "{arguments}.0",
|
166 | "{that}.options.allowMethods",
|
167 | "{that}.options.origin",
|
168 | "{that}.options.credentials"
|
169 | ]
|
170 | }
|
171 | }
|
172 | });
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | kettle.middleware.CORSHandle = function (request, allowMethods, origin, credentials) {
|
182 | var res = request.res,
|
183 | req = request.req,
|
184 | reqOrigin = req.headers.origin;
|
185 |
|
186 | allowMethods = fluid.makeArray(allowMethods).concat(["OPTIONS", "PUT", "POST"]);
|
187 |
|
188 |
|
189 | res.header("Access-Control-Allow-Origin",
|
190 | origin === "*" || origin.indexOf(reqOrigin) > -1 ? reqOrigin : "null");
|
191 | res.header("Access-Control-Allow-Credentials", credentials);
|
192 | res.header("Access-Control-Allow-Methods", allowMethods.join(","));
|
193 | res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
|
194 |
|
195 | if (req.method === "OPTIONS") {
|
196 | res.sendStatus(204);
|
197 | }
|
198 | return fluid.promise().resolve();
|
199 | };
|
200 |
|
201 |
|
202 | fluid.defaults("kettle.middleware.mismatch", {
|
203 | gradeNames: "kettle.middleware",
|
204 | invokers: {
|
205 | handle: "kettle.middleware.mismatch.handle"
|
206 | }
|
207 | });
|
208 |
|
209 | kettle.middleware.mismatch.handle = function (request) {
|
210 | if (request.req.mismatchError) {
|
211 | return fluid.promise().reject(request.req.mismatchError);
|
212 | }
|
213 | };
|
214 |
|
215 | fluid.defaults("kettle.middleware.cookieParser", {
|
216 | gradeNames: ["kettle.plainMiddleware"],
|
217 | secret: null,
|
218 | middlewareOptions: {},
|
219 | middleware: "@expand:kettle.npm.cookieParser.json({that}.options.secret, {that}.options.middlewareOptions)"
|
220 | });
|
221 |
|
222 | fluid.defaults("kettle.middleware.static", {
|
223 | gradeNames: ["kettle.plainAsyncMiddleware"],
|
224 | terms: {
|
225 | },
|
226 |
|
227 | middlewareOptions: {},
|
228 |
|
229 | middleware: "@expand:kettle.middleware.static.createMiddleware({that}.options.root, {that}.options.terms, {that}.options.middlewareOptions)"
|
230 | });
|
231 |
|
232 | kettle.middleware["static"].createMiddleware = function (root, terms, middlewareOptions) {
|
233 | if (!root) {
|
234 | fluid.fail("Static middleware must have a root path configured to serve options - got ", root);
|
235 | }
|
236 | var moduleTerms = fluid.getMembers(fluid.module.modules, "baseDir");
|
237 | var fullTerms = fluid.extend(true, moduleTerms, terms);
|
238 | var expandedRoot = fluid.stringTemplate(root, fullTerms);
|
239 | return kettle.npm.serveStatic(expandedRoot, middlewareOptions);
|
240 | };
|