/Users/kehan/yaws_apps/ %% my root for yaws apps
/Users/kehan/yaws_apps/music
/Users/kehan/yaws_apps/music/www %% the yaws docroot as set in
yaws.conf
/Users/kehan/yaws_apps/music/ebin
/Users/kehan/yaws_apps/music/src
My yaws.conf contains:
<server www.erlymusic.com>
port = 8000
listen = 192.168.1.20
docroot = /Users/kehan/yaws_apps/music/www
appmods = <"/music", erlyweb>
<opaque>
appname = music
</opaque>
</server>
All works as expected.
Here are the problems:
The generated code has a file index.html which references style.css.
Both index.html and style.css are directly under my yaws docroot as
generated by erlyweb.
Line 3 of index.html references the stylesheet:
<link rel="stylesheet" href="/music/style.css">
This is the first clue that something fishy is going on. I can enter a
url of:
www.erlymusic.com:8000 _or_ www.erlymusic.com:8000/music and get
working results of the same welcome page. I would not expect this. I
should not be able to use _both_ urls unless I were to explicitely code
my app or yaws to handle both urls as the same.
My yaws docroot is /Users/kehan/yaws_apps/music/www. This is supposed
to mean that _all_ references in html files use this as the root. For
the stylesheet ref to work as it is coded, there should be a directory
under /Users/kehan/yaws_apps/music/www called music which of course
there is not.
So there is some trickery going on here that provides for surprises and
violates what I have set as my yaws docroot.
To demonstrate this trickery and show what kind of trouble it causes,
lets try these experiments.
Lets change the yaws config so the appmod is:
appmods = <"/", erlyweb>
This is perfectly legal and setting the root as an appmod was a bug
until very recently in yaws.
Now, I can still go to www.erlymusic.com:8000 and get my friendly
welcome view. But if try to go to www.erlymusic.com:8000/music, I get
an error:
The requested URL //music was not found on this server.
Notice the two slashes instead of one.
Of course if I try to go to www.erlymusic.com:8000/musician, which was
my goal, I get an error as well:
ERROR erlang code crashed:
File: appmod:0
Reason: {badarg,[{lists,split,[-1,"/musician"]},
{erlyweb_util,get_app_root,1},
{erlyweb,ewc,2},
{erlyweb,app_controller_hook,3},
{yaws_server,deliver_dyn_part,8},
{yaws_server,aloop,3},
{yaws_server,acceptor0,2},
{proc_lib,init_p,5}]}
Req: {http_request,'GET',{abs_path,"/musician"},{1,1}}
AHH but the fun doesn't stop there...remember I have set my appmod to
"/". I can still go to
www.erlymusic.com:8000/music/musician or
www.erlymusic.com:8000/music/musician/list/1 as if I had not changed
my appmod path at all!!!
I'm sure these things can be fixed...Yariv???
thanks, ke han
This is a weird side effect of Yaw's appmod handling. If you go to
the erlyweb appmod won't be invoked. Instead, Yaws will open
'index.html' in the docroot, i.e. music/www. OTOH, if you go to
erlymusic:com:8000/music
then the erlyweb appmod will pick up the request, check if it matches
the URL of a component, and since the component part is empty, it will
return to yaws the following tuple:
{page, "/index.html"}
(in ErlyWeb 0.2.2, which I will release later today, this will change
to {page, "/"}, which is more appropriate).
This again makes Yaws open music/www/index.html.
I think that the only way you can avoid this duplication is by setting
your appmod to "/".
>
> My yaws docroot is /Users/kehan/yaws_apps/music/www. This is supposed
> to mean that _all_ references in html files use this as the root. For
> the stylesheet ref to work as it is coded, there should be a directory
> under /Users/kehan/yaws_apps/music/www called music which of course
> there is not.
> So there is some trickery going on here that provides for surprises and
> violates what I have set as my yaws docroot.
The confusion again stems from the fact that if ErlyWeb receives a
request whose path doesn't match a component, it returns to yaws a
tuple such as {page, "/path"}. For instance, lets assume you open
http://erlymusic.com/music/style.css
if 'style.css' isn't the name of a component, ErlyWeb will return to Yaws
{page, "/style.css"}
This yields the same result as navigating to
http://erlymusic.com/style.css
(assuming style.css is in the docroot, i.e. music/www/).
Assuming your appmod is set to be <"/music", erlyweb>, then the only
way to load the
>
> To demonstrate this trickery and show what kind of trouble it causes,
> lets try these experiments.
> Lets change the yaws config so the appmod is:
> appmods = <"/", erlyweb>
> This is perfectly legal and setting the root as an appmod was a bug
> until very recently in yaws.
> Now, I can still go to www.erlymusic.com:8000 and get my friendly
> welcome view. But if try to go to www.erlymusic.com:8000/music, I get
> an error:
>
> The requested URL //music was not found on this server.
>
> Notice the two slashes instead of one.
The two slashes looks like a bug. I'll fix it.
>
> Of course if I try to go to www.erlymusic.com:8000/musician, which was
> my goal, I get an error as well:
>
> ERROR erlang code crashed:
> File: appmod:0
> Reason: {badarg,[{lists,split,[-1,"/musician"]},
> {erlyweb_util,get_app_root,1},
> {erlyweb,ewc,2},
> {erlyweb,app_controller_hook,3},
> {yaws_server,deliver_dyn_part,8},
> {yaws_server,aloop,3},
> {yaws_server,acceptor0,2},
> {proc_lib,init_p,5}]}
> Req: {http_request,'GET',{abs_path,"/musician"},{1,1}}
That's a bug. I'll fix it.
>
> AHH but the fun doesn't stop there...remember I have set my appmod to
> "/". I can still go to
> www.erlymusic.com:8000/music/musician or
> www.erlymusic.com:8000/music/musician/list/1 as if I had not changed
> my appmod path at all!!!
>
That's because of the weird way Yaws handles appmods. As long as a
substring of the path component matches the appmod directive in
yaws.conf, Yaws forwards the request to the appmod (the substring
doesn't have to start from index 0). Check out this page for more info
(it's the 'prepath' string):http://yaws.hyber.org/appmods.yaws. I
should probably add a check in ErlyWeb to make sure the prepath length
is 0 because this behavior is too weird.
> I'm sure these things can be fixed...Yariv???
Will do :)
Cheers,
Yariv
Actually, this isn't even a prepath issue. It looks like a bug in
Yaws, where Yaws forwards requests such as
to ErlyWeb, passing it an appmoddata of "/musician" even when the
appmod directive in yaws.conf is
appmods = <"/", erlyweb>
Yariv
Correction: This is a byproduct of what looks like a Yaws bug. When
you set your appmods directive in yaws.conf to
appmods = <"/music", erlyweb>
and then you navigate to http://localhost:8000/music/music, you get
the error message "The requested URL /music was not found on this
server." (Note the single slash, which is correct.)
However, when you set your appmods directive to
appmods = <"/", erlyweb>
and then you navigate to http://localhost:8000/music, you get the
error message, "The requested URL //music was not found on this
server." Now you get the double slash.
I will add a workaround to this bug in ErlyWeb by checking for a
leading slash, but this should still be fixed in Yaws because it is
causing other problems.
Yariv