Use Node-RED as reverse proxy

Hey Walter (@krambriw), I try to add as much information as possible. Novice users won't need it, but as soon as they become more advanced they know where to find it. But if it isn't clear for skilled people like you, I definitely have to find a way to simplify my explanation somehow. Will keep you updated ...

If I'm not mistaken, I have read somewhere that Nick regretted that he had introduced (in the past) the exchange of the http request/response objects via messages. But not sure about it !!!!!!!!!! I thought because you could run into problems since those objects cannot simply be converted to json. For example in the future there will be pluggable custom wiring mechanisms, so I assume you cannot simply pass the request/response objects in messages - via some 'remote' wire - to another Node-RED instance.
Therefore I don't think this is the way to go when you want streaming ...

Paul (@zenofmud), unbelievable that you have read to the end of my readme :joy:. I find this very suspicious ... Or you are some kind of masochist, or your Chinese nanny has teached you read from bottom to top?
I have removed the open end, which means there will be no sequel next year...

2 Likes

But...but...now I'll never know if the butler actually did it :sob:

(while I read it, I never said I understood it :blush:)

2 Likes

I have read through the code on my mobile, a few notes:

  1. can we receieve the config from msg? The usual trick is to set parameters like
const url = msg.params.url || config.url;
  1. seems error event from http-proxy is not handled, not sure what would happen if there is error (e.g. Target url not found)

  2. is it possible to return a msg instead of directly send the http response? Some people may want to post process the proxy result

  3. will the response header "polluted" by the proxy's response header? One of your use case is to hide internal resource link and you will definitely not hoping for exposing proxy headers to actual response header

Hi Bart, what you have written is fine, I do understand. Eventually what could be better highlighted is the absolute benefits & advantages & why. I had some difficulties to really get that at first glance

What I mean is maybe best explained with a typical use case example related to my own needs & thoughts. Assume I would like to build a gui for video viewing & management. If I do this "without thinking" I quickly go ahead and configure a Dashboard with direct links to my ip-cameras. This you can easily do out-of-the-NR-box

If I then lack a middle-ware in between handling the logon, like Motion does, I would reveal the credentials of my cameras (just have to use the inspect function in the browser). This might be ok if you just restrict viewing while on your local home network. But as soon as you would like to expose to the outside or have concerns that not everyone on the same network should have access, then you will face problems. I can imagine if setting up a small/midsize NR system with video managing as a commercial product, this would certianly be something to worry about

I do not know if this was a good example since I might have a setup that is already taking care of stuff like this. My setup is as below and maybe Motion actualy works as a proxy server when connecting ip cameras? And I access my home network from outside via VPN. Only thing not protected is that anyone connected to our home network can access the Dashboard

IP & USB Cameras <-> Motion <-> NR <-> Dashboard w Video Views <-> VPN Server <-> Router <-> Internet

Hi Keni (@kenime),
Thanks for your constructive feedback !!

I have added this functionality on Github. You can find the explanation and example flow here. I implemented it as standard Node-RED requires: the msg.url content is only be used when the URL is empty in the node's config screen (not the other way around!).

I have extended this functionality on Github. You can find the explanation and example flow here.

Perhaps I could do this, but there is a issue when you look at the modify response example of the http-proxy module that I use under the cover:

  • Finite response: when receiving a standard resource response, the data chunks should be concatenated. As soon as the entire response has arrived, an output message could be send. Otherwise the next node would have an incomplete response. But this looks very much to a standard Node-RED solution http-in --> http-request --> http-out, so I'm not sure whether it has any use to implement it here again ...
  • Infinite (stream) response: when receiving e.g. an Mjpeg stream, I cannot wait for the end of the response. So I would have to send an output message for every data chunk. But not sure what the next node could do with those individual data chunks?

That is indeed very true! But as explained above, this is my first experience with reverse proxies. So I don't know for sure if the response doesn't contain any references to the target server. Especially with all the available options ... If you (or anybody else with experience in this area) can test and verify this, please be my guest !!!! All feedback or pull requests are welcome !

Walter (@krambriw), will try to find some time this week to rewrite parts of the readme. Thanks for your tips!!

Hi Keni (@kenime ),
I did some extra tests, and I have the impression that the reverse proxy library (which I'm using behind the scenes) does something not correctly. Or I am not using it correctly somehow...

When I navigate in Chrome to my reverse-proxy node (which redirects me to httpbin.org), then I see e.g. server:nginx in the response headers:

image

I did expect to see server:Express, since Node-RED (and also the reverse proxy node) is running ExpressJs. But now Nginx is leaked, which is the webserver used to host httpbin.org ;-(

Don't see what could be going wrong. Unless somebody else can give me the golden tip, I am going to rename my node to e.g. node-red-contrib-http-redirect. I have developed this node mainly for redirecting my mjpeg streams via Node-RED, and that seems to be working fine ...

[EDIT] I'm wondering now if I should have used RedBird, which seems to be a reverse proxy build on top of node-http-proxy. Not sure anymore ...

  • Based on the above issue, I have renamed my node to node-red-contrib-http-proxy, and I have updated all above links to point to my new readme page.
  • I have added a CAUTION to the readme, to warn that some target server information 'might' leak to the client.
  • @krambriw: I have totally rewritten the readme page. Hopefully it is a bit more clear now ...

So have you unpublished/deprecated the old version from npm? And removed the node-red tag from it so we won’t index it ?

Hey Dave, fortunately I hadn't published it on npm yet. For some reason, I had a feeling it wouldn't be correct from the first time...

1 Like

Very nice indeed!!!
I have a problem trying to install, I get "error 404 Not Found: node-red-contrib-http-proxy@latest"
Is there an alternative way to install? Like starting with wget ....

try...

cd ~/.node-red  (or wherever your node-red folder is)
npm install bartbutenaers/node-red-contrib-http-proxy

Indeed, will publish it on npm this evening...

Thank you, worked fine now!!!

Just one more question; Is this node independent of the format of the data or is it basically supporting all formats? I mean, there are so many various formats/protocols (for video as example, mp4, ts, mjpeg and many more)

I would expect it to be independent. It just passes chunks of data from the target to the client. For the proxy it are just a bunch of bytes which he need to write to the response object...

It is now published on NPM and available on flows.nodered.org:

image

3 Likes

When I use this node ,it never hide my target URL .I can see the target url as browser URL .
I was expecting it to hide it.

Even though it redirect the request the target is not getting hidden.
Is this problem with my usage?

There's a caution note about this in the documentation. I assume it's a side effect of the request/response simply being forwarded. Likely it's part of the headers sent by the proxied server.

Thanks for your assistance!
Indeed this node has been developed to solve a number of problems, but it is not a full blown http proxy:

image

Can you explain that more in detail please, because with so less information I can only start guessing. Because in the browser you use an url referring to your Node-RED server, not to the target url?

1 Like

Thank you for the response .If there a way to hide target URL?