UNPKG

2.96 kBJavaScriptView Raw
1/*
2Routing Primitives for Kettle Servers
3
4Copyright 2015 Raising the Floor (International)
5
6Licensed under the New BSD license. You may not use this file except in
7compliance with this License.
8
9You may obtain a copy of the License at
10https://github.com/fluid-project/kettle/blob/master/LICENSE.txt
11*/
12
13/* Contains code adapted from express 4.x "layer.js":
14 * Copyright(c) 2009-2013 TJ Holowaychuk
15 * Copyright(c) 2013 Roman Shtylman
16 * Copyright(c) 2014-2015 Douglas Christopher Wilson
17 * MIT Licensed
18 */
19
20"use strict";
21
22var fluid = require("infusion"),
23 urlModule = require("url"),
24 kettle = fluid.registerNamespace("kettle");
25
26// Upstream dependency stolen from express 4.x
27kettle.pathToRegexp = require("path-to-regexp");
28
29fluid.defaults("kettle.router.http", {
30 gradeNames: "fluid.component",
31 members: {
32 handlers: []
33 },
34 invokers: {
35 register: {
36 funcName: "kettle.router.http.register",
37 args: ["{that}", "{arguments}.0"]
38 },
39 match: {
40 funcName: "kettle.router.http.match",
41 args: ["{that}.handlers", "{arguments}.0"]
42 }
43 }
44});
45
46
47kettle.router.http.register = function (that, handler) {
48 var prefix = handler.prefix || "";
49 handler.regexp = kettle.pathToRegexp(prefix + handler.route, handler.keys = []);
50 that.handlers.push(handler);
51};
52
53kettle.router.registerOneHandlerImpl = function (that, handler, extend) {
54 var handlerCopy = fluid.extend({
55 method: "get"
56 }, handler, extend);
57 kettle.router.http.register(that, handlerCopy);
58};
59
60kettle.router.http.decodeParam = function (val) {
61 if (typeof val !== "string" || val.length === 0) {
62 return val;
63 }
64 try {
65 return decodeURIComponent(val);
66 } catch (err) {
67 err.message = "Failed to decode request routing parameter \"" + val + "\"";
68 err.status = err.statusCode = 400;
69 throw err;
70 }
71};
72
73kettle.router.http.matchToParams = function (handler, match) {
74 var params = {};
75 for (var i = 1; i < match.length; i++) {
76 var key = handler.keys[i - 1];
77 var prop = key.name;
78 var val = kettle.router.http.decodeParam(match[i]);
79
80 if (val !== undefined) {
81 params[prop] = val;
82 }
83 }
84 return params;
85};
86
87// cf. Router.prototype.matchRequest
88kettle.router.http.match = function (handlers, req) {
89 var method = req.method.toLowerCase(),
90 parsedUrl = urlModule.parse(req.url),
91 path = parsedUrl.pathname;
92 for (var i = 0; i < handlers.length; ++i) {
93 var handler = handlers[i];
94 if (method === handler.method) {
95 var match = handler.regexp.exec(path);
96 if (match) {
97 return {
98 handler: handler,
99 output: {
100 params: kettle.router.http.matchToParams(handler, match)
101 }
102 };
103 }
104 }
105 }
106};