0 Design: Custom Node admin route handling
Nick O'Leary edited this page 2018-05-14 16:52:47 +01:00

Nodes are able to add their own custom routes to the RED.httpAdmin express app. This allows them to:

  • provide their own admin routes - such as the Serial node's ability to query active ports on the host
  • serve up additional content - such as Debug loading its shared .js library and node-red-node-geofence loading the leaflet.js library and associated resources.

Within the editor, as long as their reference those routes with a relative url, they will work regardless of what httpAdminRoot is set to.

This poses some problems for the split of the editor and runtime.

One of the goals of the split is to be able to serve the editor from a static file server (eg AWS S3) and point it at a server hosting the admin api. At this point, any relative urls a custom node uses will break - as they will be relative to the S3 url, not the admin api url.

Editor side

There are a number of ways a user may access these custom routes - each needs a slightly different solution.

Type of route Resolution
$.ajax call We already use $.ajaxSetup() to attach access tokens to relative urls. That can be updated to rewrite urls
Adding scripts to the page
$.getScript Also covered by $.ajaxSetup() fix
<script> at the top level of the HTML When we load a node's HTML content, we can parse it, look for any script tag with a relative src url and rewrite it. Prototyping this shows it then causes issues with scripts not being loaded in the same order. Will need some extra logic to find and load all external scripts first before adding node HTML content.
Any other mechanism If we cannot intercept the src url, we cannot fix. This method must be deprecated.
Adding external stylesheets to the page
<link> at the top level of the HTML As with <script> - we can parse and identify such links before adding to the DOM
<link> inside edit template <script> As with <script>, but this happens each time the edit dialog is opened for a node.
Adding images to the page
<img> in edit template As with <script>, but this happens each time the edit dialog is opened for a node.
Dynamically added via code We cannot intercept these - no good solution to keep things working as-is

So we can cover a number of the cases via code inspection and url rewriting - but not all. I don't know how common it is for nodes to add custom images - but its possible, so needs to be handled.

Changes

  • add parsing of the node's html content before initial adding to DOM to spot top level script and link tags and perform url rewriting.
  • add parsing of the node's edit template before adding to the DOM
  • update $.ajaxSetup() to rewrite relative URLs
  • provide a utility function, RED.util.getAdminUrl, that will do the url mapping. Nodes can then be updated to use this function where needed.
  • add httpAdminCors option (to mirror existing httpNodeCors option) to allow cross-domain access to the admin runtime api

Runtime side

With the split, the server side splits into two separate modules:

  • The runtime module is where nodes are registered and live.
  • The editor module provides the admin express app to expose the admin routes on an http server instance

with the new runtime-api used as the interface between them.

By splitting them like that, a node can no longer have direct access to the admin express app instance. Which is a big problem.

On the whole, they just add routes using the standard app.get/post/del/put functions. But some will do something more involved, such as add an instance of serveStatic (or similar) to serve up static content for the node, or allowing file upload.

To achieve a full split between the modules, the runtime-api needs to have some way of abstracting out these routes so they can be made over RPC. There's no nice way of doing that.