Konstantin,

Thanks for the comments. I'll make mine inline below.

On 8/24/2012 2:55 PM, Konstantin Kolinko wrote:
2012/8/25 Mark Eggers <its_toas...@yahoo.com>:
Folks,

This is not strictly a Tomcat problem, but since the application is running
under Tomcat I thought I would ask.

Environment
-----------
Tomcat:  6.0.20
JRE:     1.6.0_16
OS:      some UNIX variant

I'm a little light on the environment, since it's not mine. Yes, this is
old. No, I don't have any leverage to get them to update.

Background
----------

An application makes use of a PDF library which generates PDFs from JSP
pages. One of these pages includes a dynamically generated graph.

This library cannot use streaming data to include the graph. The only two
options are:

1. Write the graph within the web application and use relative paths
2. Write the graph somewhere else and:
    a. use a fully qualified URL point to a servlet
    b. the servlet retrieves the graph by name

Ideally, we write the JPG file to java.io.tmpdir, then reference a servlet
in the JSP to fetch the graph and insert it into the page.

Considerations
--------------

Unfortunately, in certain environments we cannot use solution 2. One of
these environments involves a NAT and hairpinning. In those cases, we use
solution 1.

We use getRealPath in a listener, tag on a directory to write images, set
the path in a singleton, and we're done. We can then use a relative
directory in the JSP to get the image and generate the PDF.

If for any reason getRealPath returns a null, we fall back to using
java.io.tmpdir.


Problem
-------

I ran into a situation where getRealPath with the above environment returns
a null, even when the WAR file is exploded.

This means that we fall back to java.io.tmpdir, and run into the hairpinning
problem.

Question
--------

What other reasons could there be for getRealPath to return a null rather
than the path where the application is run?

Some other Info
---------------

They are not running under a security manager. ps shows no security manager
arguments, and at any rate the application would throw a bunch of other
security violations and fail to start (a few getReourceAsStream issues in
listeners).

I noticed that the server appears to be running from an NFS mount. However,
the exploded WAR file directory is marked as 755, and the ownership is
correct.

About the only thing that comes to mind is NSF3 / NSF4 ACLs. I won't know
more about the server environment until Monday.

If anyone has ideas, I'd be happy to hear about them.


1. One known case is that getRealPath() will return null if the path
does not actually exist.

(In that case getResource() will return null as well).

Does getRealPath("/") work?

I'll put together a WAR file and test on Monday. Unfortunately they're East Coast USA time, which means it's 6 PM as I write this.


2. If you are guessing on ACL...  can you try whether
  new File(System.getProperty("catalina.base")).getCanonicalPath()
call succeeds?

I think that I heard that getCanonicalPath() can fail if some parent
directories do not have enough permissions on them.


I'll try this as well. I'll stuff it in the same listener, and log the results. Fortunately I log my listener stuff in a separate file, so it's pretty easy to see what failed and why.

============
3. What is your hairpinning problem?


Hairpinning is when a system is sitting behind a NAT, and it attempts to send itself a packet to the public IP address.

+----------------<
|                  NAT <----------------> Server
+---------------->
   public IP            private IP
   ww.xx.yy.zz          aa.bb.cc.dd

In this environment it occurs with a host name. The server sends a packet to itself using the publicly accessible name, which resolves to the external IP address (ww.xx.yy.zz), which then gets sent right back to the server.

Unless you specifically configure a NAT device to allow this, the packet will be dropped.

Is it because you use "a fully qualified URL point to a servlet" and
you cannot build that URL correctly?

Do you really need an absolute URL? You mean that you cannot call your
servlet otherwise?

This is correct. The library in use will only take relative URLs, or fully qualified URLs (including protocol, port, and host name).

Relative URLs means I write back into the web application, which is where getRealPath() comes into play.

I cannot use absolute URLs (/context/servlet-name?imagename=foo). This gets interpreted by the library as an absolute file name (and no, using /java.io.tmpdir/foo does not work).

I would love to rewrite my URL to be

http://localhost:80/context/servlet-name?imagename=foo

That will only work if there are no virtual hosts in any front end proxy and no additional hosts in server.xml.

I could write a separate application that serves the image files internally. It would be quite simple to do, but it would potentially require server modifications.

1. Listens to requests on a separate port (server.xml modification)
2. Application resides in the default host (for multi-host configs)

Then the path would look something like the following.

A. Request

Browser  ------------> NAT ------------> Server
          public IP            private IP
          ww.xx.yy.zz          aa.bb.cc.dd

B. Image

+-----< Server
|         ^
|         |  localhost - some arbitrary port
+---------+

C. Resulting PDF

Browser  <------------ NAT <------------ Server
          public IP            private IP
          ww.xx.yy.zz          aa.bb.cc.dd


Best regards,
Konstantin Kolinko

Thanks for the thoughts. I'll construct a test WAR file and see how fast I can get them to deploy it.

I like my separate application solution as the most generic. It also keeps me from writing back into the web application (something I hate to do). I just don't know how flexible they'll be in adding this complexity to their environment.

. . . . just my two cents.
/mde/


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to