In Express.js, is there a standard way to re-order the middleware registered on an express#Router object? I have a situation where it is possible to dynamically register static asset directories that should be served by the app via express.static(). However, the Router#use() method (which I'm using to register the new asset directories) always puts middleware at the end of Router#stack. I want this to be at the beginning. Is there any way to achieve this?
I have a working implementation that basically traverses the current Router's stack in reverse, picks the first middleware called staticMiddleware, and moves it from that location to the front of the array. This works, but is obviously dependent on the internals of Route. I'm hoping there's another, more standard way to achieve the same behavior.
You probably want to just have a custom route at the beginning of the order that can examine the path, compare it to a list of directories you want to serve (that can change over time) and then serve the static content if its path matches.
This would just be a smarter version of express.static() that works off a dynamic path list rather than only a pre-defined path. There isn't much to express.static() so you can just copy it into your function and make it smarter.
It is apparently possible to crack into the stack of middleware and modify the order. I don't know if this is a supported capability or just something unsupported that people have figured out (that could break in the future). Here's one article that discusses this: https://www.exratione.com/2013/03/nodejs-abusing-express-3-to-enable-late-addition-of-middleware/
Related
Say I want to have an apparent directory that, via the browser, is http://whatever/images/
But on the file system, it actually draws from both /Users/me/www/images and /Users/me/moreimages/. So if I request http://whatever/images/selfie.jpg, it will first look for /Users/me/www/images/selfie.jpeg, and if that isn't found, serve /Users/me/moreimages/selfie.jpeg instead.
I can think of some ugly ways of doing this, handling the routing and serving myself, but I'd like to do it in the most "correct" and hopefully straightforward way. Does express have some workaround where I can cause it to do this?
Yes, this is possible. Just have two instances of express.static both mounted on /images:
router.use('/images', express.static('/Users/me/images/'));
router.use('/images', express.static('/Users/me/moreimages/'));
If the request is not satisfied in the first instance of the middleware, the second one will be processed, and so on.
Are there a good way to get async data from an EJS file?
Sails.js only have async methods to get data from a database.
I have a collection of Pages with their associated content Values. In some cases I want to get a specific Value from another Page (e.g.: in a related page module, a navigation module...). And I need to do that server side, to keep the front-end part SEO friendly.
The easier way should be to retrieve all the Pages and Values inside the controller, and then expose a function to my EJS to get the specific data I need. But I really don't want to retrieve each time all the data from a collection.
I'm working on a CMS so I would avoid creating a new controller/view for each specific cases that I will have.
EDIT:
It seems there is no good way to do that, so I reworked my controller to make it a bit more intelligent. It solve my problem for now.
Assuming I understand you correctly....
data is sent to the view by passing an object into the view funciton
return res.view({data: "important data"});
I'm guessing that you want to call a method for some specific data mid-render. Because having all the data ready on the res.view() call is too slow. As far as I know this is not possible. That would almost certainly be "blocking" code.
Best option I could recommend is to grab specific data using ajax on the client after page load. One of the best features of using sails :)
I'd like to get a few things cleared up about playlist folder handling in Libspotify. A few things seem a bit inconsistent about it (I get the impression folder handling has been hacked in as a bit of an afterthought?)
When I cycle through all the playlists in a container, I notice I get the same sp_playlist handle value for all the folders. This means I can't use any of sp_playlist_xxx functions on folders, right? So I can't register callbacks on them, cannot find out their name, etc?
Instead, I have to use special functions on the PlaylistContainer to get folder names?
Is it dangerous to use sp_playlist_add_ref and sp_playlist_release on handles pointing to folders?
Also, what is the sp_playlistcontainer_playlist_folder_id function intended for?
Your assumptions are mostly correct. Folder placeholders in the playlist container list are just that - placeholders.
Instead, I have to use special functions on the PlaylistContainer to get folder names?
Yes, sp_playlistcontainer_playlist_folder_name().
Is it dangerous to use sp_playlist_add_ref and sp_playlist_release on handles pointing to folders?
Not especially, as long as you don't over-release somewhere, but that's true of everything. You'll just have multiple owning references to the placeholder, which is fine.
Also, what is the sp_playlistcontainer_playlist_folder_id function intended for?
It's a unique ID for the folder, mainly there since you can't use the pointer as a unique identifier since all folders use the same placeholder object. It allows you to compare folders to one another without doing string comparison on the name (which, since multiple folders can have the same name, isn't actually a good idea).
Why do we want to have another require structure inside a require structure?
like
require([mod1,mod2], function(m1, m2){
require([mod3], function(m3){
// and then will use m1 and m2 here as well
})
})
Why can't we just have one require structure? I want to understand the motivation between this setup.
Nested require isn't mandatory, and can easily be avoided if this don't fit your style.
Although, this can be useful to load submodules or conditional modules (like a polyfill).
In a more personal experience, I often use nested require inside my router controller in order to load certain page view when they're requested. This allow me to request only the dependencies of my router without loading the entire page collection of an app.
I also often find myself using nested require to manage some i18n aspect of some apps by loading conditional locale.
Last thing, I'd just remember that modules should be defined using define, not require. require function is really used to arbitrary load scripts if needed (and can be use once to bootstrap your app). So in most of the real use case, you'll have some nested require inside a define module definition.
Hope this help!
I've got some source code that has some cross site scripting vulnerabilities in it. There is no input validation that happens when the browser sends data over to the server which is executing server-side Javascript and classic ASP (IIS 7.0).
My question is, is there a way to override the Request.Form("foo") object/method so that I can call a sanitization function too and get rid of prohibited JS/HTML? I don't want to do a find and replace on every single file everywhere Request.Form is called. I was hoping for something more elegant.
Any suggestions are appreciated.
I don't think you can change Request.Form members.
What you can do, as a partial solution, is to create a code that will run first on every page (for example, using an include directive) which loops over Request.Form, Request.QueryString etc., and if it finds suspected code, it terminates the code execution (Response.End). This solution is partial because it doesn't really sanitize input, it just drops execution when it finds suspected text.
Another option: Create an array, parallel to Request.Form. Populate this array with the same members as in Request.Form, but this time sanitized. Then, quickly do a Find-and-Replace over your whole code base, and change Request.Form to your custom array variable.
There is a way to replace the whole Request object with another COM object but its an insane solution and it would still require that all ASP files that use Form contain a common top include file. Its not possible to replace the Request object or one of its members globally at the application level.
The correct solution to the problem, your statement "don't want to do a find and replace on every single file everywhere" notwithstanding, is to perform such global replace.
Despite the number of .asp files that exist the cost is no more than knocking up a simple program to open each ASP file in a folder tree, adding an include line and replacing Request.Form.