sandy98 / node-simple-router Goto Github PK
View Code? Open in Web Editor NEWYet another minimalistic router for node.js
Home Page: node-simple-router.herokuapp.com
License: MIT License
Yet another minimalistic router for node.js
Home Page: node-simple-router.herokuapp.com
License: MIT License
Would it be possible to add routing for OPTIONS
POST, GET, PUT, PATCH, DELETE and ANY already exist but the ability to deal with a "pre-flight" OPTIONS request explicitly, would be very useful, like this maybe:
route.options('*', function(req,res) {
var headers = {};
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = true;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept";
// respond to the request
res.writeHead(200, headers);
res.end();
});
I'm trying to let my node app precompile coffee script files. But how can I intercept these requests? When app.get '/:file', (req, res) ->
doesn't work, because when requesting a file, the router always automatically searches for it and then returns a 404. Is there any way to turn the file server off?
Hi,
I am going to route a HEAD request by means of an 'any' function. The problem is the library prints the above error although it routes the request. In the handler I need to add a listener for 'end' event. So it never fires!
Best,
Afshin
2013-12-27T23:15:28.136121+00:00 app[web.1]: /app/node_modules/node-simple-router/lib/router.js:160
2013-12-27T23:15:28.136650+00:00 app[web.1]: for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2013-12-27T23:15:28.137123+00:00 app[web.1]: ^
2013-12-27T23:15:28.141908+00:00 app[web.1]: TypeError: Cannot read property 'length' of undefined
2013-12-27T23:15:28.141908+00:00 app[web.1]: at Server.dispatch (/app/node_modules/node-simple-router/lib/router.js:160:31)
2013-12-27T23:15:28.141908+00:00 app[web.1]: at Server.args.(anonymous function) (/app/node_modules/nodetime/lib/core/proxy.js:131:20)
2013-12-27T23:15:28.141908+00:00 app[web.1]: at Server.EventEmitter.emit (events.js:98:17)
2013-12-27T23:15:28.141908+00:00 app[web.1]: at HTTPParser.parser.onIncoming (http.js:2108:12)
2013-12-27T23:15:28.141908+00:00 app[web.1]: at HTTPParser.parserOnHeadersComplete as onHeadersComplete
2013-12-27T23:15:28.141908+00:00 app[web.1]: at Socket.socket.ondata (http.js:1966:22)
2013-12-27T23:15:28.141908+00:00 app[web.1]: at TCP.onread (net.js:525:27)
We are trying a simple route.any to implement the catch-all case, but it never gets invoked (sending many unsupported url calls).
Does this work at all ?
Thanks.
Hi, i just noticed that if my json POST contains '=' then it will not be parsed correctly by the server. I see there's been some commit related to this problem 4 days ago, but after updating to 0.9.3-1 i don't see an improvement.
{
"log": {
"version": "1.2",
"creator": {
"name": "WebInspector",
"version": "537.36"
},
"pages": [],
"entries": [
{
"startedDateTime": "2014-11-21T19:04:29.609Z",
"time": 338.3598327636719,
"request": {
"method": "POST",
"url": "http://localhost:9800/test",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Origin",
"value": "http://localhost:9800"
},
{
"name": "Accept-Encoding",
"value": "gzip, deflate"
},
{
"name": "Host",
"value": "localhost:9800"
},
{
"name": "Accept-Language",
"value": "pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2,de;q=0.2"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36"
},
{
"name": "Content-Type",
"value": "application/json;charset=UTF-8"
},
{
"name": "Accept",
"value": "application/json, text/plain, /"
},
{
"name": "Referer",
"value": "http://localhost:9800/editor.html?id=maptest1"
},
{
"name": "Cookie",
"value": "49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupTop=245; 49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupLeft=563; 49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupWidth=677.1999998092651; 49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupHeight=325.19999980926514; Iguana-FileBrowserPath-7B13D17CA70A4742FDFBA45FB8DE5273=C:\tools\iNTERFACEWARE\Iguana\test\input; 885347ABE141B42402FDF850AD0BB06F_admin_PopupWidth=677.1999998092651; 885347ABE141B42402FDF850AD0BB06F_admin_PopupHeight=325.19999980926514; csrftoken=bUvCmd6HiWPC9oCHTBkeZ6QTFznRXCIT; 7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupWidth=717.1999998092651; 7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupHeight=399.19999980926514; 7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupTop=253; 7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupLeft=553; 885347ABE141B42402FDF850AD0BB06F_admin_PopupTop=290; 885347ABE141B42402FDF850AD0BB06F_admin_PopupLeft=573; EDTprojectPaneWidth=224px; EDTdockHeight=101px; version_notification_close_date=; m=3247:t|6967:t|34e2:|796a:t|2c69:t|77cb:t|47ba:t|ca3:t|2a03:t|18c3:t|54e1:t; nsr_sid=6b28c77e-9dd1-4f9f-a2fc-24f3be5ffe07"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Content-Length",
"value": "5328"
}
],
"queryString": [],
"cookies": [
{
"name": "49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupTop",
"value": "245",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupLeft",
"value": "563",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupWidth",
"value": "677.1999998092651",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "49294B5EEB22B2D32CFAB7CAB9E94AC3_admin_PopupHeight",
"value": "325.19999980926514",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "Iguana-FileBrowserPath-7B13D17CA70A4742FDFBA45FB8DE5273",
"value": "C:\tools\iNTERFACEWARE\Iguana\test\input",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "885347ABE141B42402FDF850AD0BB06F_admin_PopupWidth",
"value": "677.1999998092651",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "885347ABE141B42402FDF850AD0BB06F_admin_PopupHeight",
"value": "325.19999980926514",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "csrftoken",
"value": "bUvCmd6HiWPC9oCHTBkeZ6QTFznRXCIT",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupWidth",
"value": "717.1999998092651",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupHeight",
"value": "399.19999980926514",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupTop",
"value": "253",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "7D3AF7DB410E8DACB86D9D14979607D8_admin_PopupLeft",
"value": "553",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "885347ABE141B42402FDF850AD0BB06F_admin_PopupTop",
"value": "290",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "885347ABE141B42402FDF850AD0BB06F_admin_PopupLeft",
"value": "573",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "EDTprojectPaneWidth",
"value": "224px",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "EDTdockHeight",
"value": "101px",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "version_notification_close_date",
"value": "",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "m",
"value": "3247:t|6967:t|34e2:|796a:t|2c69:t|77cb:t|47ba:t|ca3:t|2a03:t|18c3:t|54e1:t",
"expires": null,
"httpOnly": false,
"secure": false
},
{
"name": "nsr_sid",
"value": "6b28c77e-9dd1-4f9f-a2fc-24f3be5ffe07",
"expires": null,
"httpOnly": false,
"secure": false
}
],
"headersSize": 1591,
"bodySize": 5328,
"postData": {
"mimeType": "application/json;charset=UTF-8",
"text": "{"map":{"version":4,"title":"patientRegistration","inputMessageType":"","outputMessageType":"","description":"this is some mapping","requires":[],"customFunctions":"function gimmex() {\nreturn 'X';\n}","theMap":[{"destination":"personalInfo:firstName","id":"#0#0","sect":0,"pos":0,"defaultValue":"","remarks":"","source":"="},{"destination":"personalInfo:middleName","id":"#0#1","sect":0,"pos":1,"defaultValue":null,"remarks":"","source":"gimmex()"},{"destination":"personalInfo:lastName","id":"#0#2","sect":0,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:previousLastName","id":"#0#3","sect":0,"pos":3,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:gender","id":"#0#4","sect":0,"pos":4,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:dob","id":"#0#5","sect":0,"pos":5,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:ssn","id":"#0#6","sect":0,"pos":6,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:maritalStatus","id":"#0#7","sect":0,"pos":7,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:address1","id":"#1#0","sect":1,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:address2","id":"#1#1","sect":1,"pos":1,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:city","id":"#1#2","sect":1,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:state","id":"#1#3","sect":1,"pos":3,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:zipCode","id":"#1#4","sect":1,"pos":4,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:homePhone","id":"#1#5","sect":1,"pos":5,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:cellPhone","id":"#1#6","sect":1,"pos":6,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:workPhone","id":"#1#7","sect":1,"pos":7,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:phoneForMessage","id":"#1#8","sect":1,"pos":8,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:email","id":"#1#9","sect":1,"pos":9,"defaultValue":null,"remarks":"","source":null},{"destination":"providerPharmacy:referringProvider","id":"#2#0","sect":2,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"providerPharmacy:primaryCareProvider","id":"#2#1","sect":2,"pos":1,"defaultValue":null,"remarks":"","source":null},{"destination":"providerPharmacy:preferredPharmacy","id":"#2#2","sect":2,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"providerPharmacy:pharmacyLocation","id":"#2#3","sect":2,"pos":3,"defaultValue":null,"remarks":"","source":null},{"destination":"providerPharmacy:pharmacyPhoneNumber","id":"#2#4","sect":2,"pos":4,"defaultValue":null,"remarks":"","source":null},{"destination":"other:language","id":"#3#0","sect":3,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"other:race","id":"#3#1","sect":3,"pos":1,"defaultValue":null,"remarks":"","source":null},{"destination":"other:ethnicity","id":"#3#2","sect":3,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"other:employmentStatus","id":"#3#3","sect":3,"pos":3,"defaultValue":null,"remarks":"","source":null},{"destination":"other:employer","id":"#3#4","sect":3,"pos":4,"defaultValue":null,"remarks":"","source":null},{"destination":"other:HDYHAU","id":"#3#5","sect":3,"pos":5,"defaultValue":null,"remarks":"","source":null},{"destination":"other:HDYHAU:details","id":"#3#6","sect":3,"pos":6,"defaultValue":null,"remarks":"","source":null},{"destination":"emergencyContact:name","id":"#4#0","sect":4,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"emergencyContact:relationship","id":"#4#1","sect":4,"pos":1,"defaultValue":null,"remarks":"","source":null},{"destination":"emergencyContact:phoneNumber","id":"#4#2","sect":4,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"guardian:minorOrhaveGuardian","id":"#5#0","sect":5,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:guardianFirstName","id":"#6#0","sect":6,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:guardianMiddleName","id":"#6#1","sect":6,"pos":1,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:guardianLastName","id":"#6#2","sect":6,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:guardianRelation","id":"#6#3","sect":6,"pos":3,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:guardianPhone","id":"#6#4","sect":6,"pos":4,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:kinFirstName","id":"#7#0","sect":7,"pos":0,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:kinMiddleName","id":"#7#1","sect":7,"pos":1,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:kinLastName","id":"#7#2","sect":7,"pos":2,"defaultValue":null,"remarks":"","source":null},{"destination":"personalInfo:kinRelation","id":"#7#3","sect":7,"pos":3,"defaultValue":null,"remarks":"","source":null}]},"inputData":{}}"
}
},
"response": {
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Date",
"value": "Fri, 21 Nov 2014 19:04:30 GMT"
},
{
"name": "Transfer-Encoding",
"value": "chunked"
}
],
"cookies": [],
"content": {
"size": 79,
"mimeType": "text/plain",
"compression": -11
},
"redirectURL": "",
"headersSize": 108,
"bodySize": 90
},
"cache": {},
"timings": {
"blocked": 2.43799999589101,
"dns": 310.274000046775,
"connect": 1.1139999842270072,
"send": 0.42200001189502245,
"wait": 23.293999955057984,
"receive": 0.817832769825884,
"ssl": -1
},
"connection": "90899"
}
]
}
}
NSR in npm is with version 0.3.3, how to update it to the newest one?
I like to use to utils in NSR, but current version in npm does not have it.
Thanks!
How would i instruct the router to log to a file instead of the console ?
There are some errors when handling invalid multipart-data:
TypeError: Cannot read property 'split' of undefined
at _multipartparser (./node_modules/node-simple-router/lib/router.js:354:47)
at IncomingMessage. (./node_modules/node-simple-router/lib/router.js:137:26
......
The code at that positon is:
boundary = content_type.split(/;\s+/)[1].split('=')[1].trim();
May I modify this code to(javascript):
_multipartparser = function(body, content_type) {
var boundary, i, len1, m, obj, part, parts, resp;
resp = {
"multipart-data": []
};
// boundary = content_type.split(/;\s+/)[1].split('=')[1].trim(); // -- the old code
boundary = content_type.split(/;\s+/)[1];
if (boundary) {
boundary = boundary.split('=')[1];
if (boundary) {
boundary = boundary.trim();
parts = body.split("--" + boundary);
for (i = 0, len1 = parts.length; i < len1; i++) {
part = parts[i];
if (part && part.match(/Content-Disposition:/i)) {
obj = {};
m = part.match(/Content-Disposition:\s+(.+?);/i);
if (m) {
obj.contentDisposition = m[1];
}
m = part.match(/name="(.+?)"/i);
if (m) {
obj.fieldName = m[1];
}
m = part.match(/filename="(.+?)"/i);
if (m) {
obj.fileName = m[1];
}
m = part.match(/Content-Type:\s+(.+?)\s/i);
if (m) {
obj.fileType = m[1];
} else {
obj.fileType = 'text/plain';
}
m = part.match(/Content-Length:\s+(\d+?)/i);
if (m) {
obj.contentLength = m[1];
}
m = part.match(/\r\n\r\n/);
if (m) {
obj.fileData = part.slice(m.index + 4, -2);
obj.fileLen = obj.fileData.length;
}
resp['multipart-data'].push(obj);
}
}
}
}
return resp;
};
and the coffee script is:
_multipartparser = (body, content_type) ->
resp = "multipart-data": []
# boundary = content_type.split(/;\s+/)[1].split('=')[1].trim() #-- the old code
boundary = content_type.split(/;\s+/)[1]
if boundary
boundary = boundary.split('=')[1]
if boundary
boundary = boundary.trim()
parts = body.split("--#{boundary}")
for part in parts
if part and part.match(/Content-Disposition:/i)
#dispatch.log "PART: #{part}"
obj = {}
m = part.match(/Content-Disposition:\s+(.+?);/i)
if m
obj.contentDisposition = m[1]
m = part.match(/name="(.+?)"/i)
if m
obj.fieldName = m[1]
m = part.match(/filename="(.+?)"/i)
if m
obj.fileName = m[1]
m = part.match(/Content-Type:\s+(.+?)\s/i)
if m
obj.fileType = m[1]
else
obj.fileType = 'text/plain'
m = part.match(/Content-Length:\s+(\d+?)/i)
if m
obj.contentLength = m[1]
m = part.match /\r\n\r\n/
if m
obj.fileData = part.slice(m.index + 4, -2)
obj.fileLen = obj.fileData.length
resp['multipart-data'].push obj
resp
First of all, thanks for node-simple-router, it is my GOTO router whenever i need to spin up a quick node API server. The minimalist community thanks you dearly :D
I've recently come to a project where i can possibly have an email address in a part of the URL : http://someserver.co/endpoint/[email protected]/action . Unfortunately this is not allowed by the default regex in router.coffee.
After a bit of fiddling around in the code, i found that regex
is actually exposed as an option, so i just initialized my router with :
const router = new Router({
regex: "/([A-Za-z0-9_\\-\\.@]+)"
})
Nothing ground-breaking but i figured it might be worthwhile to either change the default regex (although there might be some unintended side-effects - i'll let you be the judge of that), or at the very least document regex
in the README. I am more than willing to propose a PR depending on what choice you land on.
Cheers,
DAM
How do you add a custom 404 page?
can we get support for cache-control by default for assets in /public?
See:
var router = new Router({logging: true, static_route: __dirname});
router.get("/", router.dispatch._404);
I don't want to the path "/" list dirs, but orther path still normal.
I saw the function “dispatch._404” in router.js。I want to call directly,but mistake:
TypeError: Cannot read property '_404' of undefined
help!
Currently this option is only available on the 'home' path, it would be quite useful to have this in subdirectories, too.
I added a route that looks as follows
router.get('/:referral'...
but unfortunately this route catches everything, including other defined routes. I tried moving it to the bottom and top of the router file to no avail. What's the best way to configure priorities around these routes. Specifically how do I make it so that NSR only hits the referral route if no other routes match?
Hello,
Is it possibile to handle multipart upload request?
Thanks
I ran into this issue when using a route to upload a file NSR was stripping out double quotes after parsing the body into request.post. After digging through, I found out that JSON.parse returns a string with the quotes stripped (it should either throw an error or return an object) even though the input is just a string. Please try the code below in console to replicate the error.
var str = '"hello"';
console.log(JSON.parse(str));
// returns hello removing the quotes
var str = '"hello';
console.log(JSON.parse(str));
// throws SynraxError exception as it should
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.