RE: getRealPath is a bad idea?
> From: Christopher Schultz [mailto:ch...@christopherschultz.net] > Subject: Re: getRealPath is a bad idea? > I would use a well-known location for the file. Maybe the application > can be installed anywhere, but the config file needs to be in > %APPDATA%\YourCompany\YourProduct\config.properties An alternative is to have the customer define the location in a Java system property via setenv.bat (or sevice properties) when installing the webapp. (I know, not pretty, but it's the webapp doing the lookup, not Tomcat.) - Chuck THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: getRealPath is a bad idea?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Cris, On 3/10/17 2:02 PM, Berneburg, Cris J. - US wrote: > Chris > > Thanks for taking the time to help me out. I appreciate it. > Sorry, my response is kinda wordy. :-P > >> If you really REALLY want a file path, you could use the >> catalina.base system property or the tmpdir and go from there. >> The former is Tomcat-specific, of course, and the tmpdir would >> be *anywhere*, but if you just really REALLY need a path on the >> disk, you could get it from there. > > Aha! Yes, that could work. It will work, but it's going to suck. :( >>> Also, maybe I'm not asking the right question. How do you all >>> configure the location of a special folder that is not part of >>> the deployment package itself? A site-specific config file >>> perhaps? >> >> Well-known location like /etc/myapp/config.cfg? Well-known >> configuration URL like >> https://internal-config.myapp.com/config.cfg? > > Actually it's Windows. Also, the config file should live in a > folder that is (1) obvious and (2) we have access to. > >>> Currently I'm using getRealPath for a relative-path location >> [SNIP] >> >> If the file can be bundled with the WAR file (which would be >> best), then you should get >> ServletContext.getResource("/path/rooted/in/the/WAR/file/config.cfg") . > >> >> > Unfortunately it's a site-specific configuration, meaning the > value for the setting may be different for each environment, so it > really cannot be bundled as-is. The file would need to be tweaked > before starting the webapp. > > Well, I suppose it could be bundled if, after deploying the > webapp, we extracted the config file, modified it for the current > location, and then reinserted it into the WAR file... But that > sounds like a lot of work and not what you intended anyway. ;-) > Actually, that's exactly how we handle other custom settings, only > without using a WAR file. It's clumsy, and I wish there were a > better way of doing it. So instead of having to tweak the > configuration after every deployment, we would only do it 1x for > the first time the application is installed. That would be great. That's super-ugly. Better to have an external configuration file. That supports the Principle of Least Surprise[1]. > I'm not sure I understand how to configure a custom resource or am > even grasping the concept. Can the resource (config file > location) be defined in the application context web.xml? If so, > wouldn't it already be too late since that would mean the config > file is already bundled with the application? Unless the location > of the config file in the resource definition can be expressed as > an OS-path (not virtual) to point outside of the webapp's home. I would use a well-known location for the file. Maybe the application can be installed anywhere, but the config file needs to be in %APPDATA%\YourCompany\YourProduct\config.properties Would that be okay? Or are you saying that you need to do things like configure the JNDI DataSource that would usually be in context.xml? > Guess I could explain it better. It's a custom report-generation > engine. A template file is read by a library, processed, dumped > to an output file, then served to the client. There is a folder > with template input files and another folder with the output > files. Neither of those are in the WAR, right? Obviously, not the output files, but what about the input templates? > Based on what you and Chuck said, it looks like the input > templates can be claimed as Resources. Since the library can accept > a java.io.InputStream, then the input templates could be included > in a WAR file, if we used one. Be specific when you use a term like "Resources". That has a special meaning to Tomcat, and actually multiple meanings depending upon the context. Which did you mean, here? You can certainly include the templates in the WAR file, but I suspect that one of your features is clients being able to build their own templates? > However, the output folder needs to live outside a WAR file, and > we need a non-virtual way of specifying the folder (an actual OS > path) so the library can write the output there. AND we currently > don't use a WAR file. But we could, provided the config file issue > can be taken care of. If so, how do you resolve a virtual path to > a resource outside the WAR file since it's outside the package > "folder" structure of the WAR? To WAR or not to WAR, that isn't really the question. But you should always work as if you were confined to a WAR file. To directly answer your question about translating virtual paths to real paths, the answer is "you can't (at least not reliably)". > Hence the use of getRealPath, so all this configuration juggling > can simply be bypassed. > > I feel like I'm stuck in a "which came first, the chicken or the > egg" loop. I would go for a well-known-location and just tell your customers "the config file has to go HERE". Maybe
RE: getRealPath is a bad idea?
Chris Thanks for taking the time to help me out. I appreciate it. Sorry, my response is kinda wordy. :-P > If you really REALLY want a file path, you could use the catalina.base system > property or the tmpdir and go from there. The former is Tomcat-specific, of > course, and the tmpdir would be *anywhere*, but if you just really REALLY need > a path on the disk, you could get it from there. Aha! Yes, that could work. >> Also, maybe I'm not asking the right question. How do you all >> configure the location of a special folder that is not part of the >> deployment package itself? A site-specific config file perhaps? > > Well-known location like /etc/myapp/config.cfg? Well-known > configuration URL like https://internal-config.myapp.com/config.cfg? Actually it's Windows. Also, the config file should live in a folder that is (1) obvious and (2) we have access to. >> Currently I'm using getRealPath for a relative-path location > [SNIP] > > If the file can be bundled with the WAR file (which would be best), then you > should get > ServletContext.getResource("/path/rooted/in/the/WAR/file/config.cfg"). Unfortunately it's a site-specific configuration, meaning the value for the setting may be different for each environment, so it really cannot be bundled as-is. The file would need to be tweaked before starting the webapp. Well, I suppose it could be bundled if, after deploying the webapp, we extracted the config file, modified it for the current location, and then reinserted it into the WAR file... But that sounds like a lot of work and not what you intended anyway. ;-) Actually, that's exactly how we handle other custom settings, only without using a WAR file. It's clumsy, and I wish there were a better way of doing it. So instead of having to tweak the configuration after every deployment, we would only do it 1x for the first time the application is installed. That would be great. I'm not sure I understand how to configure a custom resource or am even grasping the concept. Can the resource (config file location) be defined in the application context web.xml? If so, wouldn't it already be too late since that would mean the config file is already bundled with the application? Unless the location of the config file in the resource definition can be expressed as an OS-path (not virtual) to point outside of the webapp's home. Guess I could explain it better. It's a custom report-generation engine. A template file is read by a library, processed, dumped to an output file, then served to the client. There is a folder with template input files and another folder with the output files. Based on what you and Chuck said, it looks like the input templates can be claimed as Resources. Since the library can accept a java.io.InputStream, then the input templates could be included in a WAR file, if we used one. However, the output folder needs to live outside a WAR file, and we need a non-virtual way of specifying the folder (an actual OS path) so the library can write the output there. AND we currently don't use a WAR file. But we could, provided the config file issue can be taken care of. If so, how do you resolve a virtual path to a resource outside the WAR file since it's outside the package "folder" structure of the WAR? Hence the use of getRealPath, so all this configuration juggling can simply be bypassed. I feel like I'm stuck in a "which came first, the chicken or the egg" loop. -- Cris Berneburg CACI Lead Software Engineer - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: getRealPath is a bad idea?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Cris, On 3/10/17 12:56 PM, Berneburg, Cris J. - US wrote: > Chuck > >>> How do you all configure the location of a special folder that >>> is not part of the deployment package itself? A site-specific >>> config file perhaps? >> >> Take a look at this: >> http://tomcat.apache.org/tomcat-8.5-doc/config/resources.html >> >> A element within allows specification of >> areas outside of the Tomcat deployment that the webapp can access >> via ServletContext .getResource() or getResourceAsStream(). > > Thanks for pointing that out. Hmm... It looks like > getResourceAsStream might work. We use a library to processes the > files. Currently we supply it with a java.io.File as an input > source, but the library also can accept a java.io.InputStream for > input too. Don't forget to close the InputStream when you are done ;) I see a ton of code like this: configureFromPropertiesFile(app.getResourceAsStream("/config.file")) I suspect the JVM does finally close all that junk up, but it's really bad programming practice IMHO. - -chris -BEGIN PGP SIGNATURE- Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJYwu8eAAoJEBzwKT+lPKRYxuEQAKdgNAu6UvD1MM7faL/BrIzX VnYoBlpMwJ8wEWBRqtg7MrLkhzCFnhrtO/hhVxc2tAeliz2Pk7VlXMv34vlt/uCl r/t+o4lPju9WsJaT1AmjkytBGLum9Ab5VBMbmsS/jtyiJ9iC/ghR0VbJJG6yB3B9 +Ycbfb9wodLXJ5UYzzNEuLBOndR3P1etw1OSRRxdG8g8eI3GPYM+L8NeqP7s9jhf 9up3PbT0k1GOo4Jhqo1bvzBoMEfVptQKn2E+QzrtaeYcMNPS7Slr79gWG8jBYEeV cfIDxhQ1nIabmT4Rqke1K/Ek/duTRXXIuPj1QNVSr0uEgi3pgfaNgQCyhwjj32+l U1PFOXeADoCh/ofzpGUoxnkXhXNXCNPFdjvmpjUwahB6x1YqgIPqOEZvIbuCiAnT yPlBncszQlpurrsmR7AWvW28p8NhScjwYYeGG6VRfBhLKMLvTrnfSeQBNcq//vfn wPSyVpn4zH28X2Mqe83VYCLXqXne5QPITffshOFYylUQPhikrSdLSgylCl6Cnoya n/cqjCmJTVrOH+BBiIOtjYZWDCvodX6E95W+pUb4BOtrdp1a5A31L58RU3hiorqo xv1ZbWWpUASNTQXJQFkJMGYNCU2aRbxgW6/65Tv6chgpF1pDa5xKN43ArVyhsoIu y1uf4m+Q8hgeM8Fvv2XA =gSr+ -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: getRealPath is a bad idea?
Chuck >> How do you all configure the location of a special folder that is not >> part of the deployment package itself? A site-specific config file perhaps? > > Take a look at this: > http://tomcat.apache.org/tomcat-8.5-doc/config/resources.html > > A element within allows specification of areas outside > of the Tomcat deployment that the webapp can access via ServletContext > .getResource() or getResourceAsStream(). Thanks for pointing that out. Hmm... It looks like getResourceAsStream might work. We use a library to processes the files. Currently we supply it with a java.io.File as an input source, but the library also can accept a java.io.InputStream for input too. -- Cris Berneburg CACI Lead Software Engineer - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: getRealPath is a bad idea?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Cris, On 3/9/17 3:18 PM, Berneburg, Cris J. - US wrote: >>> BTW, why doesn't getRealPath return the full path to the folder >>> that the WAR file is in instead of null? >> >> You mean for a call like getRealPath("/")? > > Yes, exactly! > >> Well, that would require a path to be returned to the "root" of >> the application. Let's say that ROOT.war is in >> /home/tomcat/webapps/ROOT.war and also index.html is in the >> "root" of the WAR File. >> >> If you used getRealPath("/index.html") it would, as described, >> return null -- because there's no file path that could get you to >> that file. >> >> If you used getRealPath("/") and then added "/index.html" to the >> end of it, you'd expect to be able to read index.html from the >> resulting path (/home/tomcat/webapps/index.html). Not only does >> that not work (because the file isn't there), it's not even the >> right path. The "right" path (if there even is one) would be >> something like "/home/tomcat/webapps/ROOT.war/index.html". > > While that is exactly the sort of result I would want, it does > seem kind of hackish. It isn't a response that can be supplied to a > file system to retrieve the file. It would require some sort of > analysis and parsing. So I can see why null is the safer answer, > even if I don't like it. ;-) If you really REALLY want a file path, you could use the catalina.base system property or the tmpdir and go from there. The former is Tomcat-specific, of course, and the tmpdir would be *anywhere*, but if you just really REALLY need a path on the disk, you could get it from there. >> So when the WAR is not unpacked, there really isn't any >> meaningful return value from getRealPath, even for special- cases >> like "" or "/". > > Thanks for explaining. I need to absorb all that info. > > Also, maybe I'm not asking the right question. How do you all > configure the location of a special folder that is not part of the > deployment package itself? A site-specific config file perhaps? Well-known location like /etc/myapp/config.cfg? Well-known configuration URL like https://internal-config.myapp.com/config.cfg? > Currently I'm using getRealPath for a relative-path location, but > it sounds like that may need to be changed. Fortunately, the impact > points are somewhat limited since all calls to getRealPath are > wrapped with other centralized methods. If the file can be bundled with the WAR file (which would be best), then you should get ServletContext.getResource("/path/rooted/in/the/WAR/file/config.cfg"). - -chris -BEGIN PGP SIGNATURE- Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJYwcrTAAoJEBzwKT+lPKRYYl4QAK8P3tdjGOgYZ/6MK4cj+vHb fakVPT6IKu99ACdhubH0rllxQOSnaXzi/OGxtp3QxU0HHogb/zPYeW/eky5Hmq0I G9aJnTMXcvvlpPBwB/8FymKcIExW+NtRlrzeSKxyOQY2sPHvnyaEcqQSi5Gj0fvq 7EYQ8C2D+U/n/heU0byntAAq+/vdyvTGLuH7vabjDa0BkkK8i4RDLjUWHbQhTg45 sIbmG75pexUN654uBJ9Y2cyfVC9ZI/pyhqRv4/vHq5W5OBOWI87mRmOfd5KpxQJF z8ryXW0yImyqHc5TSmFTf4uW2A+4x4r/s9V2ghQqZMmPDYIRvjcHOzmBtTk38FGm oMQhkfY46XAat480aTc35KmWMutzyMdlYERcCf0Xet+YlGQKAyjkj5xXt1X+YjnH WQmPynjJizVzrWo6spwWNrVs5uMK3+fF2y4ubRjJ8KCeSBEWK21Y0Zu8ueyeURGc KG7qfHM53uooD7+CQnfdkBFjICWJHXPGfqHEv5eHbPlGNzUQJGNg6eVLT0QjmHev cJ1JALl1K9D5O1a3tkdjDR4mgXRfXY3qWnqQOeTfEfzjcyBnIJ+0Z7KRxYNx5XOQ j+yBI7xdOndNglEtVCGj8gJARKxfhDHpvbQMhY4f4O3pUg//P6ckzGP2QgbInD8J f63TvM/Zas0u6BmmN0Do =AUo9 -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: getRealPath is a bad idea?
> From: Berneburg, Cris J. - US [mailto:cberneb...@caci.com] > Subject: RE: getRealPath is a bad idea? > How do you all configure the location of a special folder that is not part of > the > deployment package itself? A site-specific config file perhaps? Take a look at this: http://tomcat.apache.org/tomcat-8.5-doc/config/resources.html A element within allows specification of areas outside of the Tomcat deployment that the webapp can access via ServletContext.getResource() or getResourceAsStream(). - Chuck THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: getRealPath is a bad idea?
Chris >> BTW, why doesn't getRealPath return the full path to the >> folder that the WAR file is in instead of null? > > You mean for a call like getRealPath("/")? Yes, exactly! > Well, that would require a path to be returned to the "root" of > the application. Let's say that ROOT.war is in > /home/tomcat/webapps/ROOT.war and also index.html is in the > "root" of the WAR File. > > If you used getRealPath("/index.html") it would, as described, > return null -- because there's no file path that could get you > to that file. > > If you used getRealPath("/") and then added "/index.html" to > the end of it, you'd expect to be able to read index.html from > the resulting path (/home/tomcat/webapps/index.html). Not only > does that not work (because the file isn't there), it's not > even the right path. The "right" path (if there even is one) > would be something like "/home/tomcat/webapps/ROOT.war/index.html". While that is exactly the sort of result I would want, it does seem kind of hackish. It isn't a response that can be supplied to a file system to retrieve the file. It would require some sort of analysis and parsing. So I can see why null is the safer answer, even if I don't like it. ;-) > So when the WAR is not unpacked, there really isn't any > meaningful return value from getRealPath, even for special- > cases like "" or "/". Thanks for explaining. I need to absorb all that info. Also, maybe I'm not asking the right question. How do you all configure the location of a special folder that is not part of the deployment package itself? A site-specific config file perhaps? Currently I'm using getRealPath for a relative-path location, but it sounds like that may need to be changed. Fortunately, the impact points are somewhat limited since all calls to getRealPath are wrapped with other centralized methods. -- Cris Berneburg CACI Lead Software Engineer
Re: getRealPath is a bad idea?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Cris, On 3/7/17 10:27 AM, Berneburg, Cris J. - US wrote: > [SNIP] > >>> chris S>>> getRealPath is a bad idea. <<< >>> >>> For my education's sake, would you please explain that? >>> [SNIP] >> >> There is no guarantee it will return a non-null value. The >> typical reason is if the app is running from a packed WAR. Using >> it reduces the portability of your application. >> >> Mark > > Thanks for explaining that. Never occurred to me that running from > a WAR would return null. > > I used getRealPath thinking it would *increase* portability, since > yet-another-config-option would not need to be manually set (or > verified) after every deployment or in a different environment. > "Why did the such-and-so fail? Oh... I forgot to set the folder > location - again." By using getRealPath the setting never, ever > needs to be configured - it's automatic. > > But now I may need to rethink that. > > BTW, why doesn't getRealPath return the full path to the folder > that the WAR file is in instead of null? You mean for a call like getRealPath("/")? Well, that would require a path to be returned to the "root" of the application. Let's say that ROOT.war is in /home/tomcat/webapps/ROOT.war and also index.html is in the "root" of the WAR File. If you used getRealPath("/index.html") it would, as described, return null -- because there's no file path that could get you to that file. If you used getRealPath("/") and then added "/index.html" to the end of it, you'd expect to be able to read index.html from the resulting path (/home/tomcat/webapps/index.html). Not only does that not work (because the file isn't there), it's not even the right path. The "right" path (if there even is one) would be something like "/home/tomcat/webapps/ROOT.war/index.html". So when the WAR is not unpacked, there really isn't any meaningful return value from getRealPath, even for special-cases like "" or "/". - -chris -BEGIN PGP SIGNATURE- Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJYvupLAAoJEBzwKT+lPKRYinQQALRk87wqtMBXKsPf3XCm7F4L l72cqnMgqpWzSJ4fFP/yZq/TyNAH9Oewyk0i/HZNMvqJZw5539sdpyirpDLilEe3 VMW6pzWI3FRLVkUI1CtCsqrP0onm77Avlp+U0P1xjr8lF+FhgN7FWX6WifDvlV4b ugorEoH1LXnyTfadRIe7q57APnwEz5cdepCKJv5bPT5bl8UCTEv3jnodbDkKzzXY lK3ZcBSz9qXQ+F7gIedR94RmlM63jzryzlFWJXhXOIFdWCncFrSNXlJrEnu07VMH PNsZ5Pt189jzq7u4YcUaDiSgGDRnGbGpWxiFaJyc2cVVo2FbdIZwIxfrX8hSHUIR oZnJqpHLg//26ZGiVVZ89SGVIRLdcYMCulBzxmhQ7tfDdGuWkHtHEj7eGM8DTEdO q7u+dhptXArMoWxkVhVJLXU0GjUxjLyH3ftM+YSSil59ML+99qGn3VsCOi2hTB1Q S34mcSHvJmSV7EoZBa1THcDILdWPGAfA9qv3GdUyMCXVhhse+DvYuO/Iefz7UHG1 /HeHC6yjPR8i/ty76SDwND225yxY2ZLX0qSQ4HtiN5Ks2CzwQl/h15V7HJMpGWFJ CTKUFQDgefqDzHMIjVK3wGWGiY6vckiK/am/fdxKGFdT2uxMyYxZ4pw6CMR67JMs 0Ey/SBiNAyeqLihSEMri =OSuc -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: getRealPath is a bad idea?
[SNIP] >> chris S>>> getRealPath is a bad idea. <<< >> >> For my education's sake, would you please explain that? [SNIP] > > There is no guarantee it will return a non-null value. The typical reason > is if the app is running from a packed WAR. Using it reduces the portability > of your application. > > Mark Thanks for explaining that. Never occurred to me that running from a WAR would return null. I used getRealPath thinking it would *increase* portability, since yet-another-config-option would not need to be manually set (or verified) after every deployment or in a different environment. "Why did the such-and-so fail? Oh... I forgot to set the folder location - again." By using getRealPath the setting never, ever needs to be configured - it's automatic. But now I may need to rethink that. BTW, why doesn't getRealPath return the full path to the folder that the WAR file is in instead of null? -- Cris Berneburg CACI Lead Software Engineer - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: getRealPath is a bad idea?
On 02/03/17 19:59, Berneburg, Cris J. - US wrote: > Chris > > -Original Message- > From: Christopher Schultz [mailto:chris@...] > Sent: Friday, February 24, 2017 [multiple] > To: Tomcat Users List > Subject: Re: Getting application root path before servlet is initialized? > > [SNIP] > > Martin K> In order to avoid hard coding that path, > Martin K> I need a programmatic to find that value. > Martin K> Unfortunately the datasource is initialized > Martin K> before the servlet, so "getRealPath()" is > Martin K> not working yet. > > chris S>>> getRealPath is a bad idea. <<< > > For my education's sake, would you please explain that? Or is your follow-up > below the explanation? There is no guarantee it will return a non-null value. The typical reason is if the app is running from a packed WAR. Using it reduces the portability of your application. Mark > > chris S> would it be possible to store it *outside* of > chris S> the web application's on-disk footprint? That > chris S> will in fact make you more secure. Let's say > chris S> for example that a vulnerability exists in the > chris S> DefaultServlet, or one of your application's > chris S> own servlets. It allows path-traversal or > chris S> whatever. A file living in your application > chris S> will then be potentially remotely-fetchable :( > chris S> If you move that file outside of the web > chris S> application, you have a better change of > chris S> preventing that kind of thing. > > -- > Cris Berneburg > CACI Lead Software Engineer > > - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org