pkulchenko / fullmoon

Fast and minimalistic Redbean-based Lua web framework in one file.
MIT License
684 stars 30 forks source link

Index using 2 different hosts #33

Closed Propagram closed 8 months ago

Propagram commented 8 months ago

Hello! I'm using Fullmoon to run several sites on one server. Great web framework!

When setting the index for the first host, the second host becomes not found.

local fm = require("fullmoon")

fm.setRoute({
    host = "host-b.com",
    "/",
    method = "GET"
}, function(r)
    return "host-b.com OK" --> Not found here
end)

fm.setRoute({
    host = "host-a.com",
    "/",
    method = "GET"
}, function(r)
    return "host-a.com OK"
end)

fm.run()

Is there any way for the above code to work?

Suggestion: make the fm.setRoute function find routes using the host parameter as priority

Thanks in advance

pkulchenko commented 8 months ago

Interesting; can you share the actual values you use and what the host value is when it fails to match? Something like this works for me (and this is in fact what I use in my code):

fm.setRoute({"/*routewww", host = "www.foobar.com"},
  function() return fm.serveRedirect(fm.makeUrl{host = "foobar.com"}) end)
fm.setRoute({"/*routeexamples", host = "examples.foobar.com"}, function(r)
    r.host = "examples.foobar.co" -- you can reassign the host too for subsequent matches
    return false
  end)

I suspect what happens is that your second route overwrites the first route, as the route are only unique for PATH+METHOD combination. I thought I had a warning for this, but may need to check. This is why I use *label at the end of the path to make them distinct.

Suggestion: make the fm.setRoute function find routes using the host parameter as priority

Any filter you specify is going to be applied in exactly the same way, so using the host header here should work.

Propagram commented 8 months ago

Interesting; can you share the actual values you use and what the host value is when it fails to match?

-- host 1: dev.convert-2.com:8443 (fail)

fm.setRoute({
    host = "dev.convert-2.com",
    "/",             -- /*convert2
    method = "GET"
}, fm.serveContent("/convert-2/luaconvert", {
    tools = tools,
    categories = categories,
    main = main,
    title = title,
    total = #tools,
    year = os.date("%Y")
}))

-- host 2: dev.awesome-awesome.com:8443

fm.setRoute({
    host = "dev.awesome-awesome.com",
    "/",             -- /*awesome
    method = "GET"
}, fm.serveContent("/awesome-awesome/index", {}))

This is why I use *label at the end of the path to make them distinct.

Labeling worked :) how do I label paths with "/:name"?

I thought I had a warning for this, but may need to check

PATH+METHOD+HOST (if host = "...")?

Thanks!

pkulchenko commented 8 months ago

Labeling worked :) how do I label paths with "/:name"?

I'd expect "/:name*label" to work, as :name would consume whatever is consumable.

PATH+METHOD+HOST (if host = "...")?

I considered that earlier, but what makes host really special comparing to all other headers/parameters? Besides, I've seen many cases where HOST is not enough, so the user would still run into the same situation.

I have this peculiarity documented (see the third paragraph here: https://github.com/pkulchenko/fullmoon?tab=readme-ov-file#splat-parameters), but I welcome suggestion on how to make it more prominent.