because the REST service is deployed on HTTP not AJP

*Romain Manni-Bucau*
*Twitter: @rmannibucau <https://twitter.com/rmannibucau>*
*Blog: **http://rmannibucau.wordpress.com/*<http://rmannibucau.wordpress.com/>
*LinkedIn: **http://fr.linkedin.com/in/rmannibucau*
*Github: https://github.com/rmannibucau*



2013/2/6 Chet Hosey <[email protected]>

>
> That was my expectation too. But it just isn't working that way for me
> with AJP.
>
> Apache httpd is listening on port 8888 and forwarding application requests
> (/rs-test/*) to TomEE via AJP. TomEE is listening on ports 8080 for HTTP
> and 8009 for AJP requests. If the UriInfo matched the request info, then
> the port number given should be 8080 when loading an app from TomEE
> directly, and 8888 when using httpd to load the app via AJP.
>
> When I request 
> http://servername:8080/rs-**test/<http://servername:8080/rs-test/>to get 
> content directly from TomEE via HTTP, the UriInfo methods match the
> request info, which also matches the server.xml host name and HTTP
> connector port (8080). But when I request http://servername:8888/rs-**
> test/ <http://servername:8888/rs-test/> to get content from TomEE over
> AJP, UriInfo still lists the HTTP connector port (8080) instead of the
> request port (8888). The HttpServletRequest and HttpHeaders objects do
> return the request port, but UriInfo does not.
>
> What I tried:
>
>   1. Set up the environment
>         1. export TESTDIR=/tmp/test
>         2. mkdir -p $TESTDIR
>         3. export JDK_HOME=/opt/java/jdk1.7.0_11
>         4. export PATH=$JDK_HOME/bin:$PATH
>   2. Download, build, and install Apache httpd
>         1. Download and unpack httpd-2.2.23.tar.bz2
>         2. cd httpd-2.2.23
>         3. ./configure --prefix=$TESTDIR/httpd
>         4. make && make install
>   3. Download, build, and install mod_jk
>         1. Download and unpack tomcat-connectors-1.2.37-src.**tar.gz
>         2. cd tomcat-connectors-1.2.37-src/**native
>         3. ./configure --with-apxs=$TESTDIR/httpd/**bin/apxs
>         4. make && cp apache-2.0/mod_jk.so $TESTDIR/httpd/modules/
>   4. Download and unpack apache-tomee-1.5.1-jaxrs.tar.**gz
>   5. Configure Apache httpd
>         1. Edit $TESTDIR/httpd/conf/httpd.conf
>               1. Change Listen setting to port 8888 on public IP
>               2. Append the following to load and configure mod_jk:
>
>            LoadModule jk_module modules/mod_jk.so
>            JkWorkersFile $TESTDIR/httpd/conf/workers.**properties
>            JkShmFile $TESTDIR/httpd/logs/mod_jk.shm
>            JkLogFile $TESTDIR/httpd/logs/mod_jk.log
>            JkLogLevel info
>            JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
>            JkMount /rs-test/* worker1
>
>         2. Create $TESTDIR/httpd/conf/workers.**properties with the
>            following content:
>
>            worker.list=worker1
>            worker.worker1.type=ajp13
>            worker.worker1.host=localhost
>            worker.worker1.port=8009
>
>   6. Configure TomEE and create test app
>         1. Edit conf/server.xml:
>               1. Add jvmRoute="worker1" to engine configuration
>               2. Change Engine "defaultHost" and Host "name" values to
>                  external host name
>         2. Create test application
>               1. Create webapps/rs-test/WEB-INF/**classes/test directory.
>               2. Create webapps/rs-test/WEB-INF/**classes/test/TestRS.java
> with
>                  the following content:
>
>            package test;
>            import java.net.URI;
>            import javax.servlet.http.**HttpServletRequest;
>            import javax.ws.rs.*;
>            import javax.ws.rs.core.*;
>            @Path("")
>            public class TestRS {
>
>                @GET
>                @Produces({MediaType.TEXT_**PLAIN})
>                public String defaultPage(@Context UriInfo uriInfo,
>                      @Context HttpHeaders hh, @Context
>            HttpServletRequest httpServletRequest) {
>                   String response =
>                      "uriInfo.getAbsolutePath(): "
>                         + uriInfo.getAbsolutePath() + "\n"
>                      + "uriInfo.getBaseUri(): "
>                         + uriInfo.getBaseUri() + "\n"
>                      + "uriInfo.getRequestUri(): "
>                         + uriInfo.getRequestUri() + "\n"
>                      + "httpServletRequest.**getLocalAddr(): "
>                         + httpServletRequest.**getLocalAddr() + "\n"
>                      + "httpServletRequest.**getLocalName(): "
>                         + httpServletRequest.**getLocalName() + "\n"
>                      + "httpServletRequest.**getLocalPort(): "
>                         + httpServletRequest.**getLocalPort() + "\n"
>                      + "httpServletRequest.**getServerName(): "
>                         + httpServletRequest.**getServerName() + "\n"
>                      + "httpServletRequest.**getServerPort(): "
>                         + httpServletRequest.**getServerPort() + "\n\n";
>                   for (String header : hh.getRequestHeaders().keySet(**))
> {
>                      response += header + ":\n";
>                      for (String value :
>            hh.getRequestHeaders().get(**header)) {
>                         response += "\t" + value + "\n";
>                      }
>                   }
>                   return response;
>                }
>            }
>
>           3. Compile test class with javac -classpath
>              lib/javaee-api-6.0-4-tomcat.**jar:lib/servlet-api.jar
>              webapps/rs-test/WEB-INF/**classes/test/TestRS.java
>
>   7. Start services
>         1. Run apache-tomee-jaxrs-1.5.1/bin/**startup.sh to start TomEE
>         2. Run httpd/bin/apachectl start to start httpd.
>
>
>
> On Wed, Feb 6, 2013 at 1:17 AM, Romain Manni-Bucau 
> <[email protected]<mailto:
> [email protected]>**> wrote:
>
>    UriInfo matches the http request info...
>    Le 6 févr. 2013 07:16, "Chet Hosey" <[email protected]
>    <mailto:[email protected]>> a écrit :
>
>
>     > After building httpd 2.2.23 and mod_jk 1.2.37, I configured an
>    AJP proxy
>     > for the TomEE test instance and set the jvmRoute in server.xml to
>    match the
>     > worker name from workers.properties.
>     >
>     > A request through httpd shows httpd's port number for the
>     > httpServletRequest methods, but still shows the TomEE HTTP
>    connector port
>     > in the URIs returned by the uriInfo methods.
>     >
>     > Doing string replacements seems fairly inelegant but I suppose
>    it's an
>     > option for custom apps. It would be surprising to learn that the
>    only other
>     > option is to configure the TomEE instances' HTTP connectors on
>    the same
>     > port as the httpd server, since each TomEE instance would then need a
>     > dedicated IP.
>     >
>     > I've filed TOMEE-757 in JIRA, as it's hard to imagine that this
>    behavior is
>     > intended.
>     >
>     >
>     > On Tue, Feb 5, 2013 at 9:17 AM, Chet Hosey <[email protected]
>    <mailto:[email protected]>> wrote:
>     >
>     > > Ahh, that's a good thought. It was the default value of
>    "localhost".
>     > After
>     > > changing the "name" attribute on the Host entry and updating the
>     > > defaultHost on the Engine, I'm getting the expected host name
>    in the
>     > > response.
>     > >
>     > > This leads me to wonder what happens when using AJP. I'm
>    picturing a
>     > setup
>     > > where httpd runs on port 80 and proxies to multiple TomEE
>    instances via
>     > > AJP. If the HTTP connector port is still used by the UriInfo
>    methods,
>     > then
>     > > TomEE would require special access (root or authbind) to bind
>    to port 80
>     > to
>     > > work around this behavior. And it wouldn't be possible to run
>    multiple
>     > > TomEE instances on the same IP, since they'd all have to bind
>    to port 80
>     > to
>     > > ensure URI correctness.
>     > >
>     > > I'll have to experiment to find out. If I get the chance to do
>    so, I'll
>     > > report results back.
>     > >
>     > > Thanks!
>     > >
>     > >
>     > > On Tue, Feb 5, 2013 at 1:16 AM, Romain Manni-Bucau <
>     > [email protected] <mailto:[email protected]>**>wrote:
>
>     > >
>     > >> Hi,
>     > >>
>     > >> What's your host in the server.xml?
>     > >> Le 5 févr. 2013 06:30, "Chet Hosey" <[email protected]
>    <mailto:[email protected]>> a écrit :
>
>     > >>
>     > >> > I've been using apache-tomee-1.5.1-jaxrs as a platform for
>    learning
>     > >> JAX-RS
>     > >> > and have run into some confusion about UriInfo determines
>    the base
>     > URI.
>     > >> In
>     > >> > my testing the URIs returned by UriInfo include the correct port
>     > number.
>     > >> > But the host name is always "localhost", even when I'm
>    accessing TomEE
>     > >> from
>     > >> > a remote machine.
>     > >> >
>     > >> > It's possible that UriInfo is meant to build identifiers,
>    and not
>     > >> locators.
>     > >> > This would explain why it's not called UrlInfo. But the
>    design of
>     > >> > UriBuilder suggests that one should be able to call
>     > >> >
>     > >> >    uriInfo.getBaseUriBuilder()
>     > >> >          .path(User.class, "getUserInfo")
>     > >> >          .path(userId).build();
>     > >> >
>     > >> > and use the result as a hyperlink in a JAX-RS response.
>     > >> >
>     > >> > Having used mod_jk with JBoss, I know that it can override
>    the values
>     > >> > returned by HttpServletRequest methods with parameters like
>     > >> JK_LOCAL_NAME.
>     > >> > But since this is just a sandbox I'm accessing Tomcat directly,
>     > without
>     > >> an
>     > >> > Apache httpd proxy. But this led me to wonder what
>     > >> > httpServletRequest.**getlocalName() would return. So I created
>    a test
>     > >> method
>     > >> > to find out, using the following signature:
>     > >> >
>     > >> >    @GET
>     > >> >    @Produces({MediaType.TEXT_**PLAIN})
>     > >> >    public String defaultPage(@Context UriInfo uriInfo,
>     > >> >          @Context HttpHeaders hh,
>     > >> >          @Context HttpServletRequest httpServletRequest) {
>     > >> >
>     > >> > The output surprised me. The HttpServletRequest methods use the
>     > correct
>     > >> > host name and IP address, and the "Host" header uses the public
>     > address.
>     > >> > The UriInfo methods get the port correct, but they still use
>     > >> "localhost" as
>     > >> > the host name.
>     > >> >
>     > >> >    uriInfo.getAbsolutePath():
>     > >> > 
> http://localhost:8081/sample-**app-1.0-SNAPSHOT/<http://localhost:8081/sample-app-1.0-SNAPSHOT/>
>     > >> >    uriInfo.getBaseUri():
>     > 
> http://localhost:8081/sample-**app-1.0-SNAPSHOT<http://localhost:8081/sample-app-1.0-SNAPSHOT>
>     > >> >    uriInfo.getRequestUri():
>     > >> 
> http://localhost:8081/sample-**app-1.0-SNAPSHOT/<http://localhost:8081/sample-app-1.0-SNAPSHOT/>
>     > >> >    httpServletRequest.**getLocalAddr(): 1.2.3.4
>     > >> >    httpServletRequest.**getLocalName(): www.example.com
>    <http://www.example.com>
>     > >> >    httpServletRequest.**getLocalPort(): 8081
>     > >> >    httpServletRequest.**getServerName(): www.example.com
>    <http://www.example.com>
>     > >> >    httpServletRequest.**getServerPort(): 8081
>     > >> >
>     > >> >    host:
>     > >> > www.example.com:8081 <http://www.example.com:8081>
>
>     > >> >
>     > >> > Is there a way to use TomEE's embedded CXF REST
>    implementation to
>     > >> generate
>     > >> > URIs that can be used by external clients to locate other
>    resources
>     > >> within
>     > >> > the same application? Or am I making bad assumptions about
>    the purpose
>     > >> of
>     > >> > the UriInfo methods that return UriBuilders?
>     > >> >
>     > >> > -- Chet
>     > >> >
>     > >>
>     > >
>     > >
>     >
>
>
>

Reply via email to