eclipse-mosquitto / mosquitto

Eclipse Mosquitto - An open source MQTT broker
https://mosquitto.org
Other
9.12k stars 2.41k forks source link

Serving up javascript files with no mime type #3126

Open mitra42 opened 1 month ago

mitra42 commented 1 month ago

I'm running mosquitto 2.0.18 on a Mac - installed with brew install mosquitto

It has the following configuration file

listener 1883
protocol mqtt
listener 9012
protocol websockets
http_dir .
password_file ./mosquitto_passwords

In that http_dir I have a html + javascript +mqtt library client for monitoring devices. This client works if I load it directly from a local http-server.

However if I access http://localhost:9012/

I get the following error

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.

I can happily display http://localhost:9012/webcomponents.js but security won't let me load it as javascript without a mime type.

Searching the net, I find similar problem complained about with .css files on one of the mailing lists many years ago, but that message didn't appear to get a response.

It would be really nice to use mosquitto to server up the client as well rather than requiring a separate http-server, but it seems currently that only works for trivial html only sites.

Daedaluz commented 1 month ago

Personally, I'm a bit split towards the issue here. On one hand, perhaps it should manage mime types correctly (and it would indeed be nice), on the other, one has to ask the question: "how much of a webserver should mosquitto implement?".

If i'm not mistaken, the bulk logic for the webserver comes from LWS that is used to implement websocket protocol in mosquitto, and the static http server just came along with it basically. Perhaps there is some functions within the lws library that can help with this specific issue.

Personally, I just think it's better, safer, and more efficient to let mosquitto deal with, well, mqtt and a webserver deal with http files etc.

So, for me, a webserver with /mqtt websocket proxy would be the way to go for me regardless whether the broker had build in support for alot of http settings.

This way you can also put in some origin restrictions and whatnot.

ralight commented 1 month ago

@mitra42 I agree with @Daedaluz here. The best plan is to use something like nginx as a proxy to send wss://example.com/mqtt to mosquitto, and have all other web parts sent to a web server.

The new websockets implementation for mosquitto 2.1 does not use libwebsockets and gives vastly better performance, but does not include anything other than mqtt over websockets. The libwebsockets support will still exist, but will need support compiled in. In future versions I hope to drop the libwebsockets support entirely.

mitra42 commented 1 month ago

OK - your call. I'm looking at applications where complexity of setup is important - e.g. where people are setting up small servers on Raspberry Pi's to provide local MQTT in remote areas where the UX is via html/jS/CSS from phones. Getting an nginx proxy to work adds complexity to an already complex setup, while support for probably just three mime types (JS, CSS, HTML) would allow basic (static) websites with all the action in the browser.

In terms of compile time support - that's not going to be an option, the installs are going to have to be able to work off the standard (brew, apt-get etc) compiles.

Thanks anyway

ralight commented 1 month ago

The reverse proxy makes it nicer, but isn't necessary. It just means you can access everything from the same port. You could also just run a webserver on port 443 as normal, and the broker websockets on something else like 8080. It is more complex than just the broker admittedly, but easier than with the proxy.

Daedaluz commented 1 month ago

In terms of compile time support - that's not going to be an option, the installs are going to have to be able to work off the standard (brew, apt-get etc) compiles.

Just out of curiosity, how is this achieved?

This confuses me a bit; do you compile custom binaries or not? If you do, what's the issue with compile-time support? If you don't, where does the binaries come from?

I'm thiknking; if package managers are out of the question, you have to provide binaries compatible with the environment where they are supposed to run and some guide on how to set it up. Not to mention that you need to keep up with the updates, on both the environment and mosquitto.

This just sounds alot more complex (and a world of pain, especially if you need more than one environment) gernerally speaking when all the dependencies that has to be compatible with both the environment and mosquitto.

But perhaps we are speaking of two different types of complexities, or did I misunderstand what you meant by this?

On other notes: Docker is usually very good at hiding setup / heavy customization complexity.

mitra42 commented 1 month ago

@ralight - running a basic http server (like the one that comes with node) is likely to be the solution if mosquitto won't support it. Something dumb that just serves up static files since any live data will come from using the JS mqtt library to access the mosquitto server,

@Daedaluz The different package management tools for Mac, Debian, Ubuntu etc already have a specific Mosquitto version, managing different custom compiles for all the packages is not practical for a small project, so we'll have to rely on the standard compile, in the standard packages using the same configuration file. Docker is a heavyweight task to put on things like Raspberry Pi's and other small systems.

By the way - for interest - the project I'm refering to is "FrugalIot" an attempt to reduce the cost and complexity of sensor networks in LMICs (developing countries). https://github.com/mitra42/frugal-iot

Daedaluz commented 1 month ago

Ah, yes. I misunderstood.

A standard install of nginx should probably work too, just put the web-page in the default www dir and have mosquitto listen on websockets on another port - code the page to connect to that port too. This way minimal configuration is needed and the only additional thing is somewhere along sudo apt install nginx

But you will have to edit the config file mosquitto in order for it to listen to all interfaces instead of just localhost.