You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Richard Vowles <rv...@sew.co.nz> on 2000/04/01 07:44:15 UTC

Multi-homing/Virtual named hosts

Hi all,

I have just joined this list so I don't know if this is a FAQ question, but
have there been any thoughts on how to implement multi-homing? My initial
belief after reviewing the source code and the XML files is that the server
name(s) need to be added as a "primary key" on the <Context> element in the
server.xml - and recognised as such in the code. This would mean that there
could be two (or more!) contexts with a path = "", in which case the server
name is matched (in fact the server name should always be matched, probably
with comma seperated wildcard capability).

I know it isn't in the release plans for the current version but I need it
and I'm happy to implement it for inclusion in a later release version (if
someone else isn't already), but I would like to maintain adherence to the
overall structure of how it is intended to be done...

Richard
---
Richard Vowles, Infrastructure Architect, Inprise New Zealand
home-email: "mailto:rvowles@sew.co.nz, work-email: "rvowles@inprise.com"



Re: Multi-homing/Virtual named hosts

Posted by Ben Laurie <be...@algroup.co.uk>.
Glenn Nielsen wrote:
> 
> Costin Manolache wrote:
> >
> > There are 3 steps for implementing virtual hosts:
> > - change the configuration ( server.xml ) and find an intuitive way to specify
> > the
> > virtual hosts ( maybe similar with other servers).
> >
> > - add a property to Context ( host for example ) and make sure we set it at
> > startup.
> >
> 
> We use virtual hosts with apache extensively.  We find the apache config SetEnv
> very handy for setting per virtual host environment variables that are then
> visible to CGI scripts.  Of course, these apache environment variables don't
> get passed on to a servlet container.  It would be very nice if per virtual
> host properties could be set in a properties file which were then available
> from the virtual host context.
> 
> This could be something added to the Servlet/JSP spec. In addition to the
> Page, Request, Session, and Application scopes, there could be a Host scope.
> The problem of virtual host name space conflicts extends to things like
> jsp:useBean id's.  Or the application scope should only be valid on a per
> virtual host basis.

I've suggested before (but probably only privately) that it should be
possible to specify on a per-location basis which environment variables
are pushed across to the servlet. This would fix this and many other
problems without killing performance.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

Re: Multi-homing/Virtual named hosts

Posted by Costin Manolache <co...@eng.sun.com>.
With apache things are much easier - apache has great support for virtual hosts
and the information is passed to tomcat. ( the name of the vhost, as in
apache.conf).

In fact apache can also pass the context ( the name of the Location or Directory ),
and probably the script name and everything else ( except the Servlet API choosed to
not match in semantics with any web server - so we need to parse again for
path_translated and probably few other request elements ).


> This could be something added to the Servlet/JSP spec. In addition to the
> Page, Request, Session, and Application scopes, there could be a Host scope.
> The problem of virtual host name space conflicts extends to things like
> jsp:useBean id's.  Or the application scope should only be valid on a per
> virtual host basis.

I think the right thing to do is to add the notion of parent application, and host
will be just a particular type.

Costin


Re: Multi-homing/Virtual named hosts

Posted by Glenn Nielsen <gl...@voyager.apg.more.net>.
Costin Manolache wrote:
> 
> There are 3 steps for implementing virtual hosts:
> - change the configuration ( server.xml ) and find an intuitive way to specify
> the
> virtual hosts ( maybe similar with other servers).
> 
> - add a property to Context ( host for example ) and make sure we set it at
> startup.
> 

We use virtual hosts with apache extensively.  We find the apache config SetEnv
very handy for setting per virtual host environment variables that are then
visible to CGI scripts.  Of course, these apache environment variables don't
get passed on to a servlet container.  It would be very nice if per virtual
host properties could be set in a properties file which were then available
from the virtual host context.

This could be something added to the Servlet/JSP spec. In addition to the
Page, Request, Session, and Application scopes, there could be a Host scope.
The problem of virtual host name space conflicts extends to things like
jsp:useBean id's.  Or the application scope should only be valid on a per
virtual host basis.

Regards,

Glenn

----------------------------------------------------------------------
Glenn Nielsen             glenn@more.net | /* Spelin donut madder    |
MOREnet System Programming               |  * if iz ina coment.      |
Missouri Research and Education Network  |  */                       |
----------------------------------------------------------------------

Re: Multi-homing/Virtual named hosts

Posted by Serle Shuman <se...@creator.co.za>.
When considering virtual host functionality could you also address setting
of SSL certificates per virtual host. This was a big weakness in JWS2.0


----- Original Message -----
From: Costin Manolache <co...@eng.sun.com>
To: <to...@jakarta.apache.org>
Sent: Sunday, April 02, 2000 6:16 AM
Subject: Re: Multi-homing/Virtual named hosts


> Richard Vowles wrote:
>
> > Ok, makes sense now!
>
> Then you're the right person to explain that from now on, it
> seems I'm very bad at that :-)
>
> > With that message you drew two threads together of things that I didn't
> > understand:
> >
> > (a) The fact that when setContextManager is called on SimpleMapper, it
does
> > this:
> > - which in the ideal case would mean that it is subsuming all of the
> > contexts so that it can implement its own mapping. The only problem was
that
> > when I followed the code (addContext()), it does absolutely nothing,
which
> > meant that it was confusing to me. Now it makes sense, but it needs an
> > implementation.
>
> We tried to focus on moving the dubious code outside tomcat.core and clean
> up the architecture. Tocmat had a great architecture from the beginning,
but
> in time and with many "features" added the implementation was not so good.
>
> SimpleMapper is based on the old code, and we tried to keep everything
working.
> We did many changes to support apache, and it's not a good ideea to change
> everything at once. The code used to be very stable ( and I hope it still
is ) -
>
> after many rounds of testing and in previous incarnations as JWSDKs. It is
> not an efficient alghoritm ( or no mapping alghoritm at all ), but it
tries to
> be correct - and that's very important.
>
> In tomcat 3.2 we can focus on performance ( i.e. using efficient
alghoritms and
> data structures - a tree will probably do miracles), and that can be done
> without
> affecting the stability - you can create new modules, play with them, and
when
> the code is mature enough we can change the default-  and if something is
wrong
> we can go back to the (slow, ugly, old) code.
>
> In this particular case - yes, we need to implement addContext(), but
again,
> I would do it in a new module, with a clear code.
>
>
> > As for the rest of your message, I'm going to have to go and look for
those
> > other classes (Container & ContextGroup) to see what you are talking
about.
>
> Container is just a start - it represents the properties for a group of
URLs
> or locations. Right now there are 2 properties you can set - the security
> constraints and the servlet.
>
> A Container is what Apache ( and other servers ) mean by "Location"
> or "Directory" ( or Object for NES). A Context is a particular case
> of container - the servlet API makes it very special and allows a lot
> of properties to be defined only at context level, but for most web
> servers it is just one particular prefix-mapped "Location".
> ( it doesn't mean it's bad that servlet API is not as rich as the
> native api in all big web servers - simpler is better most of the time )
>
> ContextGroup doesn't exist yet - and I don't think we need it. It will be
> just a special instance of Container, and I see no reason to complicate
> the model ( I would even remove Context and have it just a special
> Container, but it's too late for that - maybe in a small revolution). But
if
> people really want to represent a virtual host as a separate interface,
> at least ( please ) use ContextGroup.
>
> If you are familiar with apache, there are only 2 objects that matter -
> directory ( == Container, with Context as the only Container where
> you can set properties in servlet model ) and request ( well, you
> also have connection, and it's bad we don't have such an object)
>
> > My only remaining concern at this time is the changed structure of the
XML
> > file when implementing VirtualHosts - I believe that to decide on a
mapping
> > is a worthwhile thing so that I can progress. I'm not sure that putting
> > Context's under ContextManager's make sense any longer. Here's why:
> >
> >     <ContextManager debug="0" home="." workDir="work" NAME="CTMGR1">
>
> I'm not sure we need to go as far as having multiple ContextManagers. You
can
> specify interceptors at Container level ( not implemented yet, of course),
and
> that
> will solve most of the problems.
>
> I think it's better to add too many features at once - adding virtual
hosts will
> be a big
> thing anyway, let's leave multiple CM for later ( at least I want to think
a bit
> more
> about what interactions we'll have in this case - it's a bit too complex
for me
> )
>
> About the syntax for virtual hosts - my only concern is to use a syntax
> that is similar with Apache's.
>
> Keep in mind that you can have multiple virtual hosts with the same
address and
> the
> same port !!!! In your example it's more difficult to express that ( since
you
> make
> the connector a property of the vhost ). I think most browsers supports
now
> that.
>
>
>
> >      <VirtualHost name="my.server.name.1" ip="a.b.c.d">
> >         <Connector
className="org.apache.tomcat.service.SimpleTcpConnector">
> >             <Parameter name="handler"
> > value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
> >             <Parameter name="port" value="8080"/>
> >         </Connector>
>
> > I suppose the point I am trying to illustrate is one that you just made
> > yourself - a ContextManager is responsible only for knowing about all
the
> > contexts that require certain handling (context interception and request
> > interception) and to allow the "stop" implementation. I don't see why a
> > VirtualHost can't use multiple contexts each of which may need different
> > facilities from different context managers. Or am I way off the rails
here?
>
> If we can specift the facilities as context properties and keep CM as
singleton
> I think it'll be much easier. Or at least it's a good start, if we find a
need
> to have
> multiple ContextManagers we can add them.
>
> The model with Containers having their own interceptors gives you almost
> the same thing and probably more flexibility.
>
> ContextManager is the entry point for adapters, and we want to be able to
> do some tricks inside - and it's much easier with only one CM.
>
>
>
>
> > As for forcing me to accept one opinion over another, I'd rather come to
a
> > concensus so that any code I write can be made available to others, as
is
> > the general idea with this sort of thing...
>
> I just wanted to say that my opinion is not better than yours. We need to
> reach a concensus, but after discussing and finding what's best for
tomcat.
>
> Costin
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
>


Re: Multi-homing/Virtual named hosts

Posted by Costin Manolache <co...@eng.sun.com>.
Richard Vowles wrote:

> Ok, makes sense now!

Then you're the right person to explain that from now on, it
seems I'm very bad at that :-)

> With that message you drew two threads together of things that I didn't
> understand:
>
> (a) The fact that when setContextManager is called on SimpleMapper, it does
> this:
> - which in the ideal case would mean that it is subsuming all of the
> contexts so that it can implement its own mapping. The only problem was that
> when I followed the code (addContext()), it does absolutely nothing, which
> meant that it was confusing to me. Now it makes sense, but it needs an
> implementation.

We tried to focus on moving the dubious code outside tomcat.core and clean
up the architecture. Tocmat had a great architecture from the beginning, but
in time and with many "features" added the implementation was not so good.

SimpleMapper is based on the old code, and we tried to keep everything working.
We did many changes to support apache, and it's not a good ideea to change
everything at once. The code used to be very stable ( and I hope it still is ) -

after many rounds of testing and in previous incarnations as JWSDKs. It is
not an efficient alghoritm ( or no mapping alghoritm at all ), but it tries to
be correct - and that's very important.

In tomcat 3.2 we can focus on performance ( i.e. using efficient alghoritms and
data structures - a tree will probably do miracles), and that can be done
without
affecting the stability - you can create new modules, play with them, and when
the code is mature enough we can change the default-  and if something is wrong
we can go back to the (slow, ugly, old) code.

In this particular case - yes, we need to implement addContext(), but again,
I would do it in a new module, with a clear code.


> As for the rest of your message, I'm going to have to go and look for those
> other classes (Container & ContextGroup) to see what you are talking about.

Container is just a start - it represents the properties for a group of URLs
or locations. Right now there are 2 properties you can set - the security
constraints and the servlet.

A Container is what Apache ( and other servers ) mean by "Location"
or "Directory" ( or Object for NES). A Context is a particular case
of container - the servlet API makes it very special and allows a lot
of properties to be defined only at context level, but for most web
servers it is just one particular prefix-mapped "Location".
( it doesn't mean it's bad that servlet API is not as rich as the
native api in all big web servers - simpler is better most of the time )

ContextGroup doesn't exist yet - and I don't think we need it. It will be
just a special instance of Container, and I see no reason to complicate
the model ( I would even remove Context and have it just a special
Container, but it's too late for that - maybe in a small revolution). But if
people really want to represent a virtual host as a separate interface,
at least ( please ) use ContextGroup.

If you are familiar with apache, there are only 2 objects that matter -
directory ( == Container, with Context as the only Container where
you can set properties in servlet model ) and request ( well, you
also have connection, and it's bad we don't have such an object)

> My only remaining concern at this time is the changed structure of the XML
> file when implementing VirtualHosts - I believe that to decide on a mapping
> is a worthwhile thing so that I can progress. I'm not sure that putting
> Context's under ContextManager's make sense any longer. Here's why:
>
>     <ContextManager debug="0" home="." workDir="work" NAME="CTMGR1">

I'm not sure we need to go as far as having multiple ContextManagers. You can
specify interceptors at Container level ( not implemented yet, of course), and
that
will solve most of the problems.

I think it's better to add too many features at once - adding virtual hosts will
be a big
thing anyway, let's leave multiple CM for later ( at least I want to think a bit
more
about what interactions we'll have in this case - it's a bit too complex for me
)

About the syntax for virtual hosts - my only concern is to use a syntax
that is similar with Apache's.

Keep in mind that you can have multiple virtual hosts with the same address and
the
same port !!!! In your example it's more difficult to express that ( since you
make
the connector a property of the vhost ). I think most browsers supports now
that.



>      <VirtualHost name="my.server.name.1" ip="a.b.c.d">
>         <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
>             <Parameter name="handler"
> value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
>             <Parameter name="port" value="8080"/>
>         </Connector>

> I suppose the point I am trying to illustrate is one that you just made
> yourself - a ContextManager is responsible only for knowing about all the
> contexts that require certain handling (context interception and request
> interception) and to allow the "stop" implementation. I don't see why a
> VirtualHost can't use multiple contexts each of which may need different
> facilities from different context managers. Or am I way off the rails here?

If we can specift the facilities as context properties and keep CM as singleton
I think it'll be much easier. Or at least it's a good start, if we find a need
to have
multiple ContextManagers we can add them.

The model with Containers having their own interceptors gives you almost
the same thing and probably more flexibility.

ContextManager is the entry point for adapters, and we want to be able to
do some tricks inside - and it's much easier with only one CM.




> As for forcing me to accept one opinion over another, I'd rather come to a
> concensus so that any code I write can be made available to others, as is
> the general idea with this sort of thing...

I just wanted to say that my opinion is not better than yours. We need to
reach a concensus, but after discussing and finding what's best for tomcat.

Costin



Re: Multi-homing/Virtual named hosts

Posted by Richard Vowles <rv...@sew.co.nz>.
Ok, makes sense now!

With that message you drew two threads together of things that I didn't
understand:

(a) The fact that when setContextManager is called on SimpleMapper, it does
this:

 this.cm=cm;
 // Add all context that are set in CM
 Enumeration enum=cm.getContextNames();
 while( enum.hasMoreElements() ) {
     String name=(String) enum.nextElement();
     try {
  Context ctx=cm.getContext( name );
  if(debug>0) ctx.log("Adding existing context " + name );
  addContext( cm, ctx );
     } catch (TomcatException ex ) {
  ex.printStackTrace();
     }
 }

- which in the ideal case would mean that it is subsuming all of the
contexts so that it can implement its own mapping. The only problem was that
when I followed the code (addContext()), it does absolutely nothing, which
meant that it was confusing to me. Now it makes sense, but it needs an
implementation.

(b) The purpose of a ContextMapper. I presumed it did what the classname
implied - it mapped something (presumably paths) to contexts, which it is
not entirely responsible for. Thats the purpose of the SimpleMapper.

As for the rest of your message, I'm going to have to go and look for those
other classes (Container & ContextGroup) to see what you are talking about.

My only remaining concern at this time is the changed structure of the XML
file when implementing VirtualHosts - I believe that to decide on a mapping
is a worthwhile thing so that I can progress. I'm not sure that putting
Context's under ContextManager's make sense any longer. Here's why:

    <ContextManager debug="0" home="." workDir="work" NAME="CTMGR1">
        <!-- ContextInterceptor
className="org.apache.tomcat.context.LogEvents" / -->
        <ContextInterceptor className="org.apache.tomcat.context.AutoSetup"
/>
        <ContextInterceptor
className="org.apache.tomcat.context.DefaultCMSetter" />
        <ContextInterceptor
className="org.apache.tomcat.context.WorkDirInterceptor" />
        <ContextInterceptor
className="org.apache.tomcat.context.WebXmlReader" />
        <ContextInterceptor
className="org.apache.tomcat.context.LoadOnStartupInterceptor" />
        <!-- Request processing -->
        <RequestInterceptor
className="org.apache.tomcat.request.SimpleMapper" debug="0" />
        <RequestInterceptor
className="org.apache.tomcat.request.SessionInterceptor" />
        <RequestInterceptor
className="org.apache.tomcat.request.SecurityCheck" />
        <RequestInterceptor className="org.apache.tomcat.request.FixHeaders"
/>
    </ContextManager>

    <ContextManager debug="0" home="." workDir="work" NAME="CTMGR2">
        <!-- ContextInterceptor
className="org.apache.tomcat.context.LogEvents" / -->
        <ContextInterceptor className="org.apache.tomcat.context.AutoSetup"
/>
        <ContextInterceptor
className="org.apache.tomcat.context.DefaultCMSetter" />
        <ContextInterceptor
className="org.apache.tomcat.context.WorkDirInterceptor" />
        <ContextInterceptor
className="org.apache.tomcat.context.WebXmlReader" />
        <ContextInterceptor
className="org.apache.tomcat.context.LoadOnStartupInterceptor" />
        <!-- Request processing -->
        <RequestInterceptor
className="org.apache.tomcat.request.SimpleMapper" debug="0" />
        <RequestInterceptor
className="org.apache.tomcat.request.SessionInterceptor" />
        <RequestInterceptor
className="org.apache.tomcat.request.SecurityCheck" />
        <RequestInterceptor className="org.apache.tomcat.request.FixHeaders"
/>
        <!-- Special Security mechanism - login or something -->
        <RequestInterceptor className="my.special.request.interceptor" />
    </ContextManager>

     <VirtualHost name="my.server.name.1" ip="a.b.c.d">
        <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
            <Parameter name="handler"
value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
            <Parameter name="port" value="8080"/>
        </Connector>

        <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
            <Parameter name="handler"
value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter name="port" value="8007"/>
        </Connector>

        <!-- example - how to override AutoSetup actions -->
        <Context path="/admin" docBase="webapps/examples" debug="0"
reloadable="true" ContextManager="CTXMGR2">
        </Context>
        <!-- example - how to override AutoSetup actions -->
        <Context path="" docBase="webapps/ROOT" debug="0" reloadable="true"
ContextManager="CTXMGR1">
        </Context>
     </VirtualHost>

     <VirtualHost name="my.server.name.2" ip="a.b.c.d">
        <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
            <Parameter name="handler"
value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
            <Parameter name="port" value="8080"/>
        </Connector>

        <Connector className="org.apache.tomcat.service.SimpleTcpConnector">
            <Parameter name="handler"
value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter name="port" value="8007"/>
        </Connector>

        <!-- example - how to override AutoSetup actions -->
        <Context path="/examples" docBase="webapps/examples2" debug="0"
reloadable="true"  ContextManager="CTXMGR1">
        </Context>

        <!-- example - how to override AutoSetup actions -->
        <Context path="" docBase="webapps/ROOT2" debug="0" reloadable="true"
ContextManager="CTXMGR1">
        </Context>
      </VirtualHost>

I suppose the point I am trying to illustrate is one that you just made
yourself - a ContextManager is responsible only for knowing about all the
contexts that require certain handling (context interception and request
interception) and to allow the "stop" implementation. I don't see why a
VirtualHost can't use multiple contexts each of which may need different
facilities from different context managers. Or am I way off the rails here?

As for forcing me to accept one opinion over another, I'd rather come to a
concensus so that any code I write can be made available to others, as is
the general idea with this sort of thing...

---
Richard Vowles, Infrastructure Architect, Inprise New Zealand
home-email: "mailto:rvowles@sew.co.nz, work-email: "rvowles@inprise.com"


----- Original Message -----
From: Costin Manolache <co...@eng.sun.com>
To: <to...@jakarta.apache.org>
Sent: Sunday, April 02, 2000 12:03 PM
Subject: Re: Multi-homing/Virtual named hosts




Re: Multi-homing/Virtual named hosts

Posted by Costin Manolache <co...@eng.sun.com>.
> > > 2) It appears that ContextManager would need to be changed to handle
> > > anything other than a simple path - was this expected?
> >
> > Context yes, I don't see the problem with ContextManager - it doesn't care
> > about virtual hosts, it just deals with Request/Responses.
>
> But this appears to be where your statement doesn't make sense - the
> SimpleMapper depends _very much_ on how contexts are stored in ContextMapper
> to find the context that is correct for the current request. Take the
> following method (from SimpleMapper)

That's because SimpleMapper is derived from old code, and it's not so simple to
explain how it evolved :-)

ContextManager has a list of all Contexts in order to implement "stop" ( to
shut down all Contexts). The fact that we have getContext ( name ) is a mistake,

that assumes unique names - probably the name should be vhost+path or
we should just remove that method.

If you use the getContext() method in CM, then you'll restrict your code to use
the Hashtable or any ( hard to change ) alghoritm that is build into
ContextManager.
Since the only use of contexts in CM is outside of the critical path, when the
server is shut down - there is no reason to optimize it. It will also make CM
very
complex - it's job is to serve as a control point, not to implement efficient
(host, path ) -> context mappings.

The right ( IMHO ) way is to construct an efficient data structure using the
addContext() notification - and in fact that's what SimpleMapper is doing in
requestMap(). Mea culpa for getContext() - I kept the old ( and simpler )
code that just used ContextManager.getContext( name ) instead of using
the internal structure.

Let me try again:  if you use CM.getContext() you put the "pressure" on
Context manager to implement the mapping, and you have no control.
If you use addContext() to construct your own structure ( and you
can use virtual host or any other property in Context - including
context init params or any other property that might be added to
context - group, etc) - then you will be able to partition and organize
everything in an optimal mode.

You may also customize the mapper based on your environment - you
may have many virtual hosts, each with one or few contexts - and you'll
use a different alghoritm if you have few hosts and many contexts.
( Hashtables are inefficient if you have few objects ). You just can't do
that customization if you hardcode the representation in your object model
( and use methods like CM.getContext( path )).

At least that was my intention when I wrote some of the code.


>     Context getContextByPath(String path) {
> ...
>         lookup:
>  do {
>      ctx = cm.getContext(path);

Bad - one reason for starting with a new mapper.

> This method is called by contextMap to determine the context that is
> required by the request - simply put, it cycles through the path request,
> lopping bits off the end until it finds one that matches a context "path"
> attribute and once found, returns it. This is my interpretation of the code.

And that's very bad too - because the same cycle will be repeated on
request map. And it's an expensive operation. It's also looking up
based on path prefix - Context path can be kept split in components
and you can do the search in the reverse direction -  most of the time
the context is flat, with one or 2 levels.

I think a much better way would be to split the context in components
and create a tree structure, then eat the request path from start to end.

We don't do that now - it's a "Simple" mapper,  but the model allows
that.


>     public Context getContext(String name) {
>  return (Context)contexts.get(name);
>     }
>
> Hmmmmmmmmmm - this means that the context is being indexed on its _path_ -
> which is absolutely no use in the situation of multiple contexts with the
> _same_ path (two virtual hosts each with / for example).

Yes, and this is a bad choice for mapping.


> This has to mean one of two things, either (a) VirtualHosts have to be
> defined OUTSIDE of ContextManagers, or (b) ContextManagers will need to deal
> with a more complex mechanism for determining the path. As I discuss this
> more and more, I am leaning towards (a) - but I have yet to figure out from
> the rather voluminous source code exactly how context managers get set...
> (any points in this regard would be helpful) (a) would also seem to map more
> closely to your comment:

I don't want to ( and can't ) force you to use one or another - I'm just listing
my
arguments and how I would do it.

My point is that ContextManager shouldn't "deal" with determining the path.
The only reason CM needs the Contexts is because it have to shut down.
It is not supposed to deal with mapping or determining the path - you should
be able to iterate and get all contexts.

For (a) - I thing a better representation is ContextGroup ( VHost is just a
particular case). We started to use Container for that, as a grouping of
contexts.

But again - the mapper is supposed to implement the mapping, and you want
to be able to plug specialized alghoritms, since this is the expensive
operation.
Container ( or ContextGroup or Context or VirtualHost) is just a data structure
with the common properties.

( Context and ContextManager are already too complex, adding mapping
alghoritms will make them imposible to read)


> Er, not quite. Again, to quote from the source code in
> Ajp12ConnectionHandler.java, in the AJP12RequestAdapter, one sees the
> following lines (readNextRequest):
>
>       contextPath = ajpin.readString(null);              file://Zone
>       // GS, the following commented line causes the Apache + Jserv + Tomcat
>       // combination to hang with a 404!!!
>       // if("ROOT".equals( contextPath ) ) contextPath="";
>       if("ROOT".equalsIgnoreCase( contextPath ) ) contextPath=null;
>       if( doLog ) log("AJP: CP=" + contextPath);
>
>       if( contextPath!= null )
>    context=contextM.getContext( contextPath );
>
> It is again, just assuming a path. This is fine if there is only one
> "virtual" host, but the host is yet to be determined (it occurs a few lines
> further down), which, if choosing the (a) option above would determine the
> contextManager to actually use in this case. My simple preference would be
> to not attempt to determine the context at all in this location.

Right - just set the informations you received from the web server.


Please not that I don't want to impose a certain solution - but I spent
a lot of time with tomcat ( and few other servers ) and this is the
result :-)

I have nothing against having a VirtualHost object ( I would prefer to
use Container, and a virtual host will be just an instance ), but I think
it's better to make the parsing and to determine the context in the
mapper interceptor, not in ContextManager or Container.

It is a very important decision - based on the object model we choose
we'll be ( or not ) able to implement certain alghoritms. If we put
part of the parsing or searching in ContextManager ( or worse, in
the adapter ) - we'll just disable some options.

Costin


Re: Multi-homing/Virtual named hosts

Posted by Richard Vowles <rv...@sew.co.nz>.
----- Original Message -----
From: Costin Manolache <co...@eng.sun.com>
To: <to...@jakarta.apache.org>
Sent: Sunday, April 02, 2000 4:34 AM
Subject: Re: Multi-homing/Virtual named hosts

Ok, it appears we are getting the wrong ends of sticks here, so I will try
and clarify my position and see how you can explain how I should progress. I
suspect this all stems a misunderstanding on my part from ContextManagers
and how they get passed around.

> > 2) It appears that ContextManager would need to be changed to handle
> > anything other than a simple path - was this expected?
>
> Context yes, I don't see the problem with ContextManager - it doesn't care
> about virtual hosts, it just deals with Request/Responses.

But this appears to be where your statement doesn't make sense - the
SimpleMapper depends _very much_ on how contexts are stored in ContextMapper
to find the context that is correct for the current request. Take the
following method (from SimpleMapper)

    Context getContextByPath(String path) {
...
        lookup:
 do {
     ctx = cm.getContext(path);
     if (ctx == null) {
         int i = path.lastIndexOf('/');
  if (i > -1 && path.length() > 1) {
      path = path.substring(0, i);
      if (path.length() == 0) {
          path = "/";
      }
  } else {
      // path too short
      break lookup;
  }
     } else {
     }
 } while (ctx == null);

 // no map - root context
 if (ctx == null) {
     ctx = cm.getContext( "" );
 }

 return ctx;
    }

This method is called by contextMap to determine the context that is
required by the request - simply put, it cycles through the path request,
lopping bits off the end until it finds one that matches a context "path"
attribute and once found, returns it. This is my interpretation of the code.

Now, lets see what that cm.getContext(path) does:

    public Context getContext(String name) {
 return (Context)contexts.get(name);
    }

Hmmmmmmmmmm - this means that the context is being indexed on its _path_ -
which is absolutely no use in the situation of multiple contexts with the
_same_ path (two virtual hosts each with / for example).

This has to mean one of two things, either (a) VirtualHosts have to be
defined OUTSIDE of ContextManagers, or (b) ContextManagers will need to deal
with a more complex mechanism for determining the path. As I discuss this
more and more, I am leaning towards (a) - but I have yet to figure out from
the rather voluminous source code exactly how context managers get set...
(any points in this regard would be helpful) (a) would also seem to map more
closely to your comment:

> ContextManager is the "controler" - it just maintain the collection of
Contexts
> ( without knowing the semantics or relation between contexts), the
> collection of interceptors ( that will know how to manipulate Req/Resp and
> Contexts) and the adapters. It doesn't have to know about what's inside
> Context or Request.

> > 4) The Ajp12 (and others?) handler would then need to be fixed to get
the
> > right context, as the context is being derived solely from the path, and
> > moved later on when the server name is found.
>
> No problem - it's done. The virtual host is already there, and all web
servers
> we support (Apache, IIS, NES ) can deal with virtual hosts.

Er, not quite. Again, to quote from the source code in
Ajp12ConnectionHandler.java, in the AJP12RequestAdapter, one sees the
following lines (readNextRequest):

      contextPath = ajpin.readString(null);               file://Zone
      // GS, the following commented line causes the Apache + Jserv + Tomcat
      // combination to hang with a 404!!!
      // if("ROOT".equals( contextPath ) ) contextPath="";
      if("ROOT".equalsIgnoreCase( contextPath ) ) contextPath=null;
      if( doLog ) log("AJP: CP=" + contextPath);

      if( contextPath!= null )
   context=contextM.getContext( contextPath );

It is again, just assuming a path. This is fine if there is only one
"virtual" host, but the host is yet to be determined (it occurs a few lines
further down), which, if choosing the (a) option above would determine the
contextManager to actually use in this case. My simple preference would be
to not attempt to determine the context at all in this location.

> > 3) The ServerName property can appear un fully qualified, which means
that
> > either (a) the server would need to fully qualify a domain name
requested
> > (which shouldn't be too nasty as the name service mechanism on the local
> > machine should have cached it) or (b) require partial matching. Which
should
> > be supported? I think partial matching will slow it down.
>
> I don't know - we should check with existing implementations ( like
apache).

Anyone out there know? It would save me a lot of work trolling through years
of feeping creaturism.

Richard


Re: Multi-homing/Virtual named hosts

Posted by Costin Manolache <co...@eng.sun.com>.
Richard Vowles wrote:

> Ok, I spent a bit of time examining SimpleMapper and ContextManager and the
> current mechanism for doing the lookup and it looks like it will take some
> serious changes to support virtual hosts without doing some silly butchering
> (as Costin indicates).
>
> I _could_ prepend a virtual hostname onto the string key that is used for
> ContextManager.getContext(path) but that appears to be a remarkably ugly
> mechanism. Here are my thoughts:
>
> 1) It would appear that VirtualHosts would need to be defined inside the
> ContextManager section of the server.xml file, this is what was in mind?

Probably that's a good solution - what I had in mind was looking at apache
( or other servers ) config and try to match. I know, there is no standard
config
file format ( and tomcat doesn't even need a "format" - server.xml is just one
way to configure tomcat in a simple case ).

Probably a new element <VirtualHost name="foo" ip="192.168.4.1" ... >
would be better. ( we can and should keep the XML model distinct from
the object model - the XML is designed for users, it's a "document", but
it can't dictate the program implementation ).

> 2) It appears that ContextManager would need to be changed to handle
> anything other than a simple path - was this expected?

Context yes, I don't see the problem with ContextManager - it doesn't care
about virtual hosts, it just deals with Request/Responses.

ContextManager is the "controler" - it just maintain the collection of Contexts
( without knowing the semantics or relation between contexts), the
collection of interceptors ( that will know how to manipulate Req/Resp and
Contexts) and the adapters. It doesn't have to know about what's inside
Context or Request.


> 3) The ServerName property can appear un fully qualified, which means that
> either (a) the server would need to fully qualify a domain name requested
> (which shouldn't be too nasty as the name service mechanism on the local
> machine should have cached it) or (b) require partial matching. Which should
> be supported? I think partial matching will slow it down.

I don't know - we should check with existing implementations ( like apache).

> 4) The Ajp12 (and others?) handler would then need to be fixed to get the
> right context, as the context is being derived solely from the path, and
> moved later on when the server name is found.

No problem - it's done. The virtual host is already there, and all web servers
we support (Apache, IIS, NES ) can deal with virtual hosts.

I think ( but haven't tried ) you can get tomcat+apache to support virtual
hosts with only few line-changes and a smart configuration. If you set
up httpd.conf with virtual hosts and servlets inside then you'll have the
information (virtualhost and location) sent to tomcat. It will be very easy
to skip any mapping and just use that info.

This may be a very good starting point - we can learn a lot from this.
( at least that's how I would start ...)

Costin


Re: Multi-homing/Virtual named hosts

Posted by Richard Vowles <rv...@sew.co.nz>.
Ok, I spent a bit of time examining SimpleMapper and ContextManager and the
current mechanism for doing the lookup and it looks like it will take some
serious changes to support virtual hosts without doing some silly butchering
(as Costin indicates).

I _could_ prepend a virtual hostname onto the string key that is used for
ContextManager.getContext(path) but that appears to be a remarkably ugly
mechanism. Here are my thoughts:

1) It would appear that VirtualHosts would need to be defined inside the
ContextManager section of the server.xml file, this is what was in mind?
2) It appears that ContextManager would need to be changed to handle
anything other than a simple path - was this expected?
3) The ServerName property can appear un fully qualified, which means that
either (a) the server would need to fully qualify a domain name requested
(which shouldn't be too nasty as the name service mechanism on the local
machine should have cached it) or (b) require partial matching. Which should
be supported? I think partial matching will slow it down.
4) The Ajp12 (and others?) handler would then need to be fixed to get the
right context, as the context is being derived solely from the path, and
moved later on when the server name is found.

Another comment, the setContextManager appears to cycle around and add the
contextManager's contexts to "itself"? I can't see the point in this given
the implementation of addContext() (in BaseInterceptor) does absolutely
nothing (as far as I can tell).

---
Richard Vowles, Infrastructure Architect, Inprise New Zealand
home-email: "mailto:rvowles@sew.co.nz, work-email: "rvowles@inprise.com"




Re: Multi-homing/Virtual named hosts

Posted by Richard Vowles <rv...@sew.co.nz>.
----- Original Message -----
From: Costin Manolache <co...@eng.sun.com>
To: <to...@jakarta.apache.org>
Sent: Saturday, April 01, 2000 6:19 PM
Subject: Re: Multi-homing/Virtual named hosts


> There are 3 steps for implementing virtual hosts:
> - change the configuration ( server.xml ) and find an intuitive way to
specify
> the
> virtual hosts ( maybe similar with other servers).
>
> - add a property to Context ( host for example ) and make sure we set it
at
> startup.

I don't quite understand why you are differentiating between these two - you
are saying something like adding a new element that defines a virtual host
and then another attribute in Context that indicates which VirtualHost(s) is
(are) being used. This seems to me to add unnecessary complexity, unless
what you are trying to do is make Tomcat a fully fledged VirtualHost
supporting web server, in which case it makes complete sense.

I haven't seen any "statement of objectives" for Tomcat (url?) so maybe I'm
missing something, is it the intention of this team to make Tomcat able to
operate like a fully functional web server?

If so, and given that I will be experimenting, any suggestions for tags - I
could make up my own, but again, if preferences exist...

> - change SimpleMapper to take into account the host property - that's the
only
> difficult part and the main reason we don't have it.
> The problem with SimpleMapper is that it's very... complex ( and is the
result
> of a long evolution and many fixes ). I would rather start a new mapper.

I suppose I had better look into it before making any value judgements!

> The mapper needs to:
> - define an efficient data structure. The most frequent operation is match
by
> prefix and vhost, then match by extension. Probably a tree or something
> - implement an efficient alghoritm - with a lot of care in parsing ( avoid
> string duplicates, etc)

Make sense - as long as I design to an interface, someone can replace my
implementation.

> You can also try to play with SimpleMapper, it shouldn't be difficult to
hack
> it, but I would rather spend the time writing a new one. There is a lot of
> theory about how to do efficient matching, and that is probably the most
> expensive operation in tomcat ( or any other server ).
>
> As a note, the API makes the parsing to be a 2 step process - you first
need to
> extract the context and then use the context config to parse the rest of
the
> request. It doesn't have to be implemented that way - it will be much
faster to
> do the full parsing in first step.
>
> I think this is one of the most important aspects of the current tomcat
design
> - we want to be able to be fast and reduce the overhead by using a smart
> alghortim, and the interceptor allows that - you'll have access to all the
> mappings and you can construct a global structure ( or partition it by
anything
> - you have control ).

So what you are saying is that you really want to replace the SimpleMapper
anyway, and if VirtualHost can be designed into it and it made faster, so
much the better.

> Please don't try to partition the problem by adding a VirtualHost object
and
> finding the host and then the context and so on. IMHO it's a bad
alghoritm, and
> doesn't fit the current model. I don't know how said it, but optimization
means
> choosing the right alghoritms and structures.

As I understand from what you just said, what you don't want is to add
another step to the process. You indicate above that it is currently a
two-step process, you don't want to add a third step? I will have to examine
the mechanism that is used at the moment to see how I can make this
possible.

Personally I don't really care at the moment about performance, I'd like to
get it operational as I want to use it on very low volume sites (10-20
requests per day), but once a mapper is written, I would be perfectly happy
to go back and discuss how to make it more efficient. I have another friend
who would like to use it on a high volume site, so it would be of personal
interest to make it work well.

Richard

---
Richard Vowles, Infrastructure Architect, Inprise New Zealand
home-email: "mailto:rvowles@sew.co.nz, work-email: "rvowles@inprise.com"




Re: Multi-homing/Virtual named hosts

Posted by Costin Manolache <co...@eng.sun.com>.
There are 3 steps for implementing virtual hosts:
- change the configuration ( server.xml ) and find an intuitive way to specify
the
virtual hosts ( maybe similar with other servers).

- add a property to Context ( host for example ) and make sure we set it at
startup.

- change SimpleMapper to take into account the host property - that's the only
difficult part and the main reason we don't have it.
The problem with SimpleMapper is that it's very... complex ( and is the result
of a long evolution and many fixes ). I would rather start a new mapper.

The mapper needs to:
- define an efficient data structure. The most frequent operation is match by
prefix and vhost, then match by extension. Probably a tree or something
- implement an efficient alghoritm - with a lot of care in parsing ( avoid
string duplicates, etc)
- receive notification when a context is added and change it's internal
structure, etc


You can also try to play with SimpleMapper, it shouldn't be difficult to hack
it, but I would rather spend the time writing a new one. There is a lot of
theory about how to do efficient matching, and that is probably the most
expensive operation in tomcat ( or any other server ).

As a note, the API makes the parsing to be a 2 step process - you first need to
extract the context and then use the context config to parse the rest of the
request. It doesn't have to be implemented that way - it will be much faster to
do the full parsing in first step.

I think this is one of the most important aspects of the current tomcat design
- we want to be able to be fast and reduce the overhead by using a smart
alghortim, and the interceptor allows that - you'll have access to all the
mappings and you can construct a global structure ( or partition it by anything
- you have control ).

Please don't try to partition the problem by adding a VirtualHost object and
finding the host and then the context and so on. IMHO it's a bad alghoritm, and
doesn't fit the current model. I don't know how said it, but optimization means
choosing the right alghoritms and structures.


Costin

Richard Vowles wrote:

> Hi all,
>
> I have just joined this list so I don't know if this is a FAQ question, but
> have there been any thoughts on how to implement multi-homing? My initial
> belief after reviewing the source code and the XML files is that the server
> name(s) need to be added as a "primary key" on the <Context> element in the
> server.xml - and recognised as such in the code. This would mean that there
> could be two (or more!) contexts with a path = "", in which case the server
> name is matched (in fact the server name should always be matched, probably
> with comma seperated wildcard capability).
>
> I know it isn't in the release plans for the current version but I need it
> and I'm happy to implement it for inclusion in a later release version (if
> someone else isn't already), but I would like to maintain adherence to the
> overall structure of how it is intended to be done...
>
> Richard
> ---
> Richard Vowles, Infrastructure Architect, Inprise New Zealand
> home-email: "mailto:rvowles@sew.co.nz, work-email: "rvowles@inprise.com"
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org