Re: URLs starting with "/web"

36 views
Skip to first unread message

Ngoc Dao

unread,
Apr 14, 2009, 2:01:59 AM4/14/09
to nitro...@googlegroups.com
Because Yaws does not serve static file at a path if there is a handler for the path, to remove the ugly "/web" for Nitrogen on Yaws, I think we can do manually like this:
1. In nitrogen_yaws_app.erl, set appmods to [{"/", wf_yaws}]
2. In wf_yaws.erl, if there is a static file at the requested path then return send back the file

Ngoc.

On Feb 9, 9:41 pm, Rusty Klophaus <rkloph...@gmail.com> wrote:
> Good question.
>
> Yes, currently Nitrogen catches everything under "/web". This decision 
> was made to put all three HTTP servers (Yaws, Mochiweb, and Inets) on 
> a level playing field.
>
> The reason is that while Mochiweb and Inets give you an opportunity to 
> inspect and handle every incoming request, Yaws instead makes you 
> assign a specific handler to a path, and will treat everything else as 
> a request for a flat file.
>
> There is definitely work being done to allow you to hook into the 
> Mochiweb or Inets loop to override this behavior. Tom McNulty is 
> leading the charge here.
>
> Best,
> Rusty
>
> On Feb 9, 2009, at 1:03 AM, pmahoney wrote:
>
>
>
> > Hello, Nitrogen beginner here.
>
> > It seems, based on wf_inets:do/1 and nitrogen_mochiweb_app:loop/2 that
> > only URLs of "/" or "/web" ++ _  are valid "nitrogen framework" URLs.
> > Everything else results in an attempt to serve a static file (or a
> > 404).
>
> > Is this an intentional design decision?
>
> > If not, what are some ways it might be changed?
>
> > nitrogen:route/1 calls wf_utils:path_to_module/1 which splits
> > arbitrary URLs into {Module, PathInfo} if the module is loaded,
> > otherwise it returns {web_404, PathInfo}.
>
> > One option would be to check the route first, and only attempt to
> > serve a static file if {web_404, _} is returned.  The route check is
> > performed for every request with inets, but only for requests that
> > don't match "web/" with mochiweb.  Is the operation too expensive to
> > perform every time?  (If so, a fairly minor patch to wf_inets.erl
> > would only call wf_platform:route/1 if Path matched "/web" ++ _).
>
> > From an aesthetic point of view, prefixing all URLs with "/web" is
> > somewhat ugly, but I suppose in the end it's mostly irrelevant.
>
> > Thanks.

Stefan Springer

unread,
Apr 14, 2009, 3:07:21 PM4/14/09
to Nitrogen Web Framework for Erlang
> > > From an aesthetic point of view, prefixing all URLs with "/web" is
> > > somewhat ugly, but I suppose in the end it's mostly irrelevant.

From my experience those things are really relevant - it is a pitty if
a good framework is rejected because of such a "minor" shortcoming.
The URL is part of the look of the website, and a developer often
cannot just decide by himself how those things should be. So if a
certain website is not supposed to have "/web" in every path, the
developer just cannot use Nitrogen.

> > only URLs of "/" or "/web" ++ _ are valid "nitrogen framework"
URLs.

I would add: If the path is "/web/...", then the module name can be
anything, as given in route/1. But if the path is "/", the module
"web_index" is used automatically (correct me if I am wrong here). It
should not be necessary to have a module with the specific name
"web_index".

ngocdaothanh

unread,
May 22, 2009, 3:36:27 PM5/22/09
to Nitrogen Web Framework for Erlang
With just a little modification, Nitrogen can run on Yaws without the
"/web" prefix. I think we could make similar modification to Inets and
Mochiweb hooks to totally remove the ugly prefix from Nitrogen.

1. nitrogen_yaws_app.erl

appmods = [{"/", wf_yaws}],

2. wf_yaws.erl

out(Arg) ->
wf_platform:init(wf_platform_yaws, Arg),
Path = Arg#arg.server_path,
{Module, PathInfo} = wf_platform:route(Path),

% If there is no web module, let Yaws return the file if it exists
% TODO: make sure that Path is inside docroot
case Module of
web_404 ->
case filelib:is_regular(filename:join(Arg#arg.docroot, PathInfo))
of
true -> {page, Path};
false -> out(Arg, Module, PathInfo)
end;

_ ->
out(Arg, Module, PathInfo)
end.

3. wf_utils.erl

tokens_to_module(Tokens, PathInfoAcc, AddedIndex) ->
try
% Try to get the name of a module.
ModuleString = "web_" ++ string:join(Tokens, "_"),
Module = list_to_existing_atom(ModuleString),

Ngoc.


On Apr 15, 4:07 am, Stefan Springer <stefan.spring...@googlemail.com>
wrote:

ngocdaothanh

unread,
May 22, 2009, 3:49:24 PM5/22/09
to Nitrogen Web Framework for Erlang
Another solution which works like that of Rails:

out(Arg) ->
% Force Yaws to serve the file first if it exists
Path = Arg#arg.server_path,
case filelib:is_regular(filename:join(Arg#arg.docroot, "." ++ Path))
of
true -> {page, Path};

false ->
wf_platform:init(wf_platform_yaws, Arg),
{Module, PathInfo} = wf_platform:route(Path),
out(Arg, Module, PathInfo)
end.

Ngoc.

Tom McNulty

unread,
May 22, 2009, 3:50:59 PM5/22/09
to nitro...@googlegroups.com
Right now /web (or any prefix) is mainly being used to route to
nitrogen pages, and any non /web prefixed URL is considered a static
file. So one alternative is to invert this, by treating any URL
prefixed with /static as a static file, and all others as a nitrogen
page.

If this becomes the default, there is probably a change that needs to
be made in the default 'route' function as well.

- Tom

chad depue/rubyrescue

unread,
May 22, 2009, 4:10:42 PM5/22/09
to Nitrogen Web Framework for Erlang
i would make the case that it's important to remove any url
restrictions if nitrogen is to receive more mainstream adoption.
Mostly this is for SEO reasons, but you could make an aesthetic
argument as well. Obviously there are workarounds for this now, such
as proxying requests in front of nitrogren through nginx or apache,
(another yaws instance?), but for SEO reasons, requiring requests to
have a specific root is bad.

Chad

Tom McNulty

unread,
May 22, 2009, 5:08:45 PM5/22/09
to nitro...@googlegroups.com
I see no problem with the fixed root if it concerns static files. As
long as this is configurable, there shouldn't be much complaint. It's
much cheaper to match a simple prefix than perform an lstat to disk on
each request. Later when you release your product, a consistent
static file prefix makes it easy to design matching rules for proxied
and static requests. And ultimately, when you become the next big
thing, your static file links will have to be rewritten to some
subdomain, CDN, etc. With a predictable path you can do that with a
simple regexp replace.

It's possible to get the above working "out-of-the-box", but it
requires effort in configuring callbacks. My vote, is that what I
have described becomes the default.

- Tom

ngocdaothanh

unread,
May 22, 2009, 5:17:32 PM5/22/09
to Nitrogen Web Framework for Erlang
+1 for the /static solution.

Ngoc.

Jon Gretar Borgthorsson

unread,
May 22, 2009, 5:27:10 PM5/22/09
to nitro...@googlegroups.com
If I remember correctly the problem is that what you are describing is not possible in yaws. There is no routing in yaws. So if the nitrogen appmod mount is /web that means /web/* is out of yaws control. Same with if you use the root for the appmod. So mapping nitrogen to the root of the app means that you cannot map something else at /static. Nitrogen would have to handle everything. Thus risking the amazing static file serving speed of yaws which is one of the mains reasons for using yaws.

Jon Gretar Borgthorsson

unread,
May 22, 2009, 5:37:40 PM5/22/09
to nitro...@googlegroups.com
Just to add to my post.

Me and Rusty talked about this a while ago. Yaws is always going to be a problem such as it is. Every solution we thought of always just smelled like an ugly hack. 

The possible solutions include hacks like adding a static file serving system in Nitrogen. And using rewrite in yaws to fake it so /$ requests are rewritten to /web/$ unless the start with /static/$. I think all of you probably feel as dirty reading these solutions as I felt writing them down. :)

So I really have to say that this is a Yaws problem. And it it can probably be solved inside Yaws in 10% of the time it would take to make a hack around it in Nitrogen.

Regards 
- Jon Gretar

Tom McNulty

unread,
May 22, 2009, 5:38:46 PM5/22/09
to nitro...@googlegroups.com
I almost didn't believe you, so I had to check an existing project running yaws (external)+nitrogen. Perhaps I encountered this problem before, as my static files were conveniently mapped to a subdomain, giving the entire root for nitrogen. 

This is pretty weak. I'll give it some thought.

- Tom

Tom McNulty

unread,
May 22, 2009, 5:54:41 PM5/22/09
to nitro...@googlegroups.com
Ugh, yeah how very annoying. 

- Tom

ngocdaothanh

unread,
Jun 30, 2009, 5:26:41 AM6/30/09
to Nitrogen Web Framework for Erlang
I think errormod_404 (http://yaws.hyber.org/yman.yaws?page=yaws.conf)
can be used to solve this problem:
* Config errormod_404 to point to wf_yaws
* In wf_yaws:out/1, if the page module is web_404 then return {page,
Path} to let Yaws try to serve static file. This time web_404 is not
used.
* If Yaws cannot find a static file, then it will call
wf_yaws:out404/3, which will call web_404. This time web_404 is
actually used.

Ngoc.

On 5月23日, 午前6:54, Tom McNulty <tom.mcnu...@cetiforge.com> wrote:
> Ugh, yeah how very annoying.
>
> - Tom
>
> On 22-May-09, at 3:37 PM, Jon Gretar Borgthorsson wrote:
>
> > Just to add to my post.
>
> > Me and Rusty talked about this a while ago. Yaws is always going to
> > be a problem such as it is. Every solution we thought of always just
> > smelled like an ugly hack.
>
> > The possible solutions include hacks like adding a static file
> > serving system in Nitrogen. And using rewrite in yaws to fake it so /
> > $ requests are rewritten to /web/$ unless the start with /static/$.
> > I think all of you probably feel as dirty reading these solutions as
> > I felt writing them down. :)
>
> > So I really have to say that this is a Yaws problem. And it it can
> > probably be solved inside Yaws in 10% of the time it would take to
> > make a hack around it in Nitrogen.
>
> > Regards
> > - Jon Gretar
>
> > On Fri, May 22, 2009 at 9:27 PM, Jon Gretar Borgthorsson <jongre...@jongretar.com
> > > wrote:
> > If I remember correctly the problem is that what you are describing
> > is not possible in yaws. There is no routing in yaws. So if the
> > nitrogen appmod mount is /web that means /web/* is out of yaws
> > control. Same with if you use the root for the appmod. So mapping
> > nitrogen to the root of the app means that you cannot map something
> > else at /static. Nitrogen would have to handle everything. Thus
> > risking the amazing static file serving speed of yaws which is one
> > of the mains reasons for using yaws.
>
> > On Fri, May 22, 2009 at 7:50 PM, Tom McNulty <tom.mcnu...@cetiforge.com

Tom McNulty

unread,
Jun 30, 2009, 1:17:09 PM6/30/09
to nitro...@googlegroups.com
Seems like that would work. I also want to see how easy it is to give
requests back to yaws for static handling, by sticking with the /
static scheme. Definitely a hack, but at a lower level than rewrites.

- Tom

ngocdaothanh

unread,
Nov 29, 2009, 8:35:36 PM11/29/09
to Tom McNulty, nitro...@googlegroups.com
This commit is really interesting:
http://github.com/klacke/yaws/commit/b7656dee696241308472756920e1ac5a854c36f4#diff-1
> >>> Right now /web (or anyprefix) is mainly being used to route to
> >>> nitrogen pages, and any non /web prefixed URL is considered a static
> >>> file. So one alternative is to invert this, by treating any URL
> >>> prefixed with /static as a static file, and all others as a nitrogen
> >>> page.
>
> >>> If this becomes the default, there is probably a change that needs
> >>> to
> >>> be made in the default 'route' function as well.
>
> >>> - Tom
>
> >>> On 22-May-09, at 1:36 PM, ngocdaothanh wrote:
>
> >>>> With just a little modification, Nitrogen can run on Yaws without
> >>> the
> >>>> "/web"prefix. I think we could make similar modification to Inets
> >>> and
> >>>> Mochiweb hooks to totally remove the uglyprefixfrom Nitrogen.
Reply all
Reply to author
Forward
0 new messages