Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "base_url" option, to "up()" to lop off referrer route path sent in from proxy servers (e.g. nginx)? #663

Open
bdklahn opened this issue Aug 2, 2023 · 7 comments

Comments

@bdklahn
Copy link

bdklahn commented Aug 2, 2023

Thanks for creating Genie!!! It is very nicely designed and full-featured.

I apologize in advance if this is already (better) handled another way, which I may have missed (maybe there are already parameters which can be passed through to HTTP.jl, or something?)

We have a setup whereby certain routes (handled by an nginx proxy server) can lead to ad-hoc services on cluster node routes (/node//).
Users can, for example, get a slurm allocation to run a Jupyter Lab session. But the proxy server seems to pass the entire ref url path to the listener service. Jupyter Lab has a "base_url" config parameter to deal with this (Jupyter server not knowing anything about the added route path).
The Pluto.jl folks were nice enough to add that to the "Pluto.run()" command.
fonsp/Pluto.jl#2225
fonsp/Pluto.jl@22be5d0

Is this something which might makes sense to add?

I am considering using Genie to spin up on-demand interactive presentation pages, maybe from some base/stock/template web app.
Thanks!

@essenciary
Copy link
Member

essenciary commented Aug 3, 2023

If I correctly understand the use case, what you are looking for is Genie.config.base_path. Configure that in your script to match the extra segment(s) in the URL. Let me know if this is what you need.

@bdklahn
Copy link
Author

bdklahn commented Aug 7, 2023

If I correctly understand the use case, what you are looking for is Genie.config.base_path. Configure that in your script to match the extra segment(s) in the URL. Let me know if this is what you need.

Thanks for the response! That certainly looks like the setting I'm interested in.
I was curious how I might have missed that in the documentation. It looks like the search function can't find "base_path".
Screenshot 2023-08-07 at 11 12 19 AM

Also, the API docs don't seem to include the kwargs (and the "code" link doesn't seem to point to any code")
Screenshot 2023-08-07 at 11 14 46 AM

I thought I recalled some documentation (in a tutorial video?) about configuration, somewhere, but then wondered if it was in your very nice book: "Web Development with Julia and Genie"
I did find a config example in "Chapter 6: Deploying Genie Apps in Production". But base_path isn't shown in the examples.

I'll give it a try, and report back, when I get a chance.
Thanks!

@bdklahn
Copy link
Author

bdklahn commented Aug 7, 2023

The good news is that, with host = "0.0.0.0", etc., the request does seem to be getting to the node running the Genie server.

The bad news is that the Genie.config.base_path setting seems to have no effect, as Genie serves a 404, on that route.

julia> Genie.config.base_path
"/node/<hostname>/8000"

404 Not Found
Sorry, we can not find /node/<hostname>/8000

That's the exact same response as I get when I . . .

julia> Genie.config.base_path = ""
""

@bdklahn
Copy link
Author

bdklahn commented Aug 7, 2023

Looking at code like the following . . .

newpath = isempty(basepath) ? route.path : basepath * route.path

. . . I wonder if this is actually the type of setting I'm looking for. That seems to be adding the base_path.
I would expect some code, somewhere, to actually remove the path from the front of the route, before passing to the router.

Maybe I simply need to make sure all routes have that prefix added to them, by setting a const variable and adding to each one.

Taking a look at . . .
https://genieframework.com/docs/genie/v5.11/tutorials/Advanced-Routing-Techniques.html
. . . I wonder if base_path will only take effect if I name the route.

I guess, either way, the route will get a name (but stable, if I assign it myself). But maybe the recommended pattern is to always build up routes via linkto().

e.g.
route(joinpath(linkto(:web_root), "sub_path")) do . . .

I guess I can learn by looking at some example web apps, maybe.

But I guess I'm still confused. Shouldn't the default up() command already be using the linkto command, incorporating the set config.base_path, whenever it resolves a route?

@bdklahn
Copy link
Author

bdklahn commented Aug 8, 2023

This function signature doesn't look right, to me. How can one assign to a default (. . . = basepath) which doesn't seem to be defined (except maybe globally, by accident)?

function to_link(route_name::Symbol, d::Dict{Symbol,T}; basepath::String = basepath, preserve_query::Bool = true, extra_query::Dict = Dict())::String where {T}

I'm just wondering if that to_link() does end up being called directly, in most cases (to resolve routes). But it then it has no knowledge of base_path.
Maybe that one is also supposed to default to the Genie.config.base_path, like this:

function to_link(route_name::Symbol; basepath::String = Genie.config.base_path, preserve_query::Bool = true, extra_query::Dict = Dict(), route_params...) :: String

?

Hmmm . . . I did not realize it was possible to assign to something undefined, in Julia.

julia> dumbfunc(arg1 = bob) = "$arg1 is dumb."
dumbfunc (generic function with 2 methods)

julia> bob
ERROR: UndefVarError: `bob` not defined

Perhaps that is allowed, to enable things to work if/when a symbol does come into scope.

Anyway, I don't see a basepath symbol in the Genie code, unless you bring the basepath function, under Configuration.jl, into scope.

@bdklahn
Copy link
Author

bdklahn commented Aug 8, 2023

I wonder if it wouldn't be better to handle the base_path in this function (@AbhimanyuAryan ?):

function route_request(req::HTTP.Request, res::HTTP.Response) :: HTTP.Response

. . . or maybe pushed down into . . .

Genie.jl/src/Router.jl

Lines 485 to 486 in 7fe0529

function match_routes(req::HTTP.Request, res::HTTP.Response, params::Params) :: Union{Route,Nothing}
endswith(req.target, "/") && req.target != "/" && (req.target = req.target[1:end-1])

. . . rather than having it only handled/called when to_link is called (apparently only intended to be used in html templates).

Because I can get my use case to work by . . .

julia> route(Genie.config.base_path, named=:web_root) do
         "Hello Web Root"
       end

But then . . .

julia> linkto(:web_root)
"/node/<hostname>/8000/node/<hostname>/8000"

. . . or is another way recommended? Can I use something like ":web_root" as a route? -or get_route().action() in a new route?

@bdklahn bdklahn changed the title Add "base_url" option, to "up()" lop off referrer route path sent in from proxy servers (e.g. ngnix)? Add "base_url" option, to "up()" to lop off referrer route path sent in from proxy servers (e.g. ngnix)? Aug 8, 2023
@bdklahn bdklahn changed the title Add "base_url" option, to "up()" to lop off referrer route path sent in from proxy servers (e.g. ngnix)? Add "base_url" option, to "up()" to lop off referrer route path sent in from proxy servers (e.g. nginx)? Aug 8, 2023
@essenciary
Copy link
Member

Related issue: GenieFramework/GenieFramework.jl#10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants