001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.jk.config;
018:
019: import java.io.File;
020: import java.io.FileWriter;
021: import java.io.IOException;
022: import java.io.PrintWriter;
023: import java.util.Date;
024:
025: import org.apache.catalina.Context;
026:
027: /**
028: Generates automatic Netscape nsapi_redirect configurations based on
029: the Tomcat server.xml settings and the war contexts
030: initialized during startup.
031: <p>
032: This config interceptor is enabled by inserting an NSConfig
033: element in the <b><ContextManager></b> tag body inside
034: the server.xml file like so:
035: <pre>
036: * < ContextManager ... >
037: * ...
038: * <<b>NSConfig</b> <i>options</i> />
039: * ...
040: * < /ContextManager >
041: </pre>
042: where <i>options</i> can include any of the following attributes:
043: <ul>
044: <li><b>configHome</b> - default parent directory for the following paths.
045: If not set, this defaults to TOMCAT_HOME. Ignored
046: whenever any of the following paths is absolute.
047: </li>
048: <li><b>objConfig</b> - path to use for writing Netscape obj.conf
049: file. If not set, defaults to
050: "conf/auto/obj.conf".</li>
051: <li><b>objectName</b> - Name of the Object to execute the requests.
052: Defaults to "servlet".</li>
053: <li><b>workersConfig</b> - path to workers.properties file used by
054: nsapi_redirect. If not set, defaults to
055: "conf/jk/workers.properties".</li>
056: <li><b>nsapiJk</b> - path to Netscape mod_jk plugin file. If not set,
057: defaults to "bin/nsapi_redirect.dll" on windows,
058: "bin/nsapi_rd.nlm" on netware, and
059: "bin/nsapi_redirector.so" everywhere else.</li>
060: <li><b>jkLog</b> - path to log file to be used by nsapi_redirect.</li>
061: <li><b>jkDebug</b> - Loglevel setting. May be debug, info, error, or emerg.
062: If not set, defaults to emerg.</li>
063: <li><b>jkWorker</b> The desired worker. Must be set to one of the workers
064: defined in the workers.properties file. "ajp12", "ajp13"
065: or "inprocess" are the workers found in the default
066: workers.properties file. If not specified, defaults
067: to "ajp13" if an Ajp13Interceptor is in use, otherwise
068: it defaults to "ajp12".</li>
069: <li><b>forwardAll</b> - If true, forward all requests to Tomcat. This helps
070: insure that all the behavior configured in the web.xml
071: file functions correctly. If false, let Netscape serve
072: static resources assuming it has been configured
073: to do so. The default is true.
074: Warning: When false, some configuration in
075: the web.xml may not be duplicated in Netscape.
076: Review the uriworkermap file to see what
077: configuration is actually being set in Netscape.</li>
078: <li><b>noRoot</b> - If true, the root context is not mapped to
079: Tomcat. If false and forwardAll is true, all requests
080: to the root context are mapped to Tomcat. If false and
081: forwardAll is false, only JSP and servlets requests to
082: the root context are mapped to Tomcat. When false,
083: to correctly serve Tomcat's root context you must also
084: modify the Home Directory setting in Netscape
085: to point to Tomcat's root context directory.
086: Otherwise some content, such as the root index.html,
087: will be served by Netscape before nsapi_redirect gets a chance
088: to claim the request and pass it to Tomcat.
089: The default is true.</li>
090: </ul>
091: <p>
092: @author Costin Manolache
093: @author Larry Isaacs
094: @author Gal Shachor
095: @author Bill Barker
096: */
097: public class NSConfig extends BaseJkConfig {
098:
099: public static final String WORKERS_CONFIG = "/conf/jk/workers.properties";
100: public static final String NS_CONFIG = "/conf/auto/obj.conf";
101: public static final String NSAPI_LOG_LOCATION = "/logs/nsapi_redirect.log";
102: /** default location of nsapi plug-in. */
103: public static final String NSAPI_REDIRECTOR;
104:
105: //set up some defaults based on OS type
106: static {
107: String os = System.getProperty("os.name").toLowerCase();
108: if (os.indexOf("windows") >= 0) {
109: NSAPI_REDIRECTOR = "bin/nsapi_redirect.dll";
110: } else if (os.indexOf("netware") >= 0) {
111: NSAPI_REDIRECTOR = "bin/nsapi_rd.nlm";
112: } else {
113: NSAPI_REDIRECTOR = "bin/nsapi_redirector.so";
114: }
115: }
116:
117: private File objConfig = null;
118: private File nsapiJk = null;
119: private String objectName = "servlet";
120:
121: public NSConfig() {
122: }
123:
124: //-------------------- Properties --------------------
125:
126: /**
127: set the path to the output file for the auto-generated
128: isapi_redirect registry file. If this path is relative
129: then getRegConfig() will resolve it absolutely against
130: the getConfigHome() path.
131: <p>
132: @param <b>path</b> String path to a file
133: */
134: public void setObjConfig(String path) {
135: objConfig = (path == null) ? null : new File(path);
136: }
137:
138: /**
139: set the path to the nsapi plugin module
140: @param <b>path</b> String path to a file
141: */
142: public void setNsapiJk(String path) {
143: nsapiJk = (path == null ? null : new File(path));
144: }
145:
146: /**
147: Set the name for the Object that implements the
148: jk_service call.
149: @param <b>name</b> Name of the obj.conf Object
150: */
151: public void setObjectName(String name) {
152: objectName = name;
153: }
154:
155: // -------------------- Initialize/guess defaults --------------------
156:
157: /** Initialize defaults for properties that are not set
158: explicitely
159: */
160: protected void initProperties() {
161: super .initProperties();
162:
163: objConfig = getConfigFile(objConfig, configHome, NS_CONFIG);
164: workersConfig = getConfigFile(workersConfig, configHome,
165: WORKERS_CONFIG);
166:
167: if (nsapiJk == null)
168: nsapiJk = new File(NSAPI_REDIRECTOR);
169: else
170: nsapiJk = getConfigFile(nsapiJk, configHome,
171: NSAPI_REDIRECTOR);
172: jkLog = getConfigFile(jkLog, configHome, NSAPI_LOG_LOCATION);
173: }
174:
175: // -------------------- Generate config --------------------
176: protected PrintWriter getWriter() throws IOException {
177: String abObjConfig = objConfig.getAbsolutePath();
178: return new PrintWriter(new FileWriter(abObjConfig, append));
179: }
180:
181: protected boolean generateJkHead(PrintWriter mod_jk) {
182: log("Generating netscape web server config = " + objConfig);
183:
184: generateNsapiHead(mod_jk);
185:
186: mod_jk.println("<Object name=default>");
187: return true;
188: }
189:
190: private void generateNsapiHead(PrintWriter objfile) {
191: objfile
192: .println("###################################################################");
193: objfile.println("# Auto generated configuration. Dated: "
194: + new Date());
195: objfile
196: .println("###################################################################");
197: objfile.println();
198:
199: objfile.println("#");
200: objfile
201: .println("# You will need to merge the content of this file with your ");
202: objfile
203: .println("# regular obj.conf and then restart (=stop + start) your Netscape server. ");
204: objfile.println("#");
205: objfile.println();
206:
207: objfile.println("#");
208: objfile.println("# Loading the redirector into your server");
209: objfile.println("#");
210: objfile.println();
211: objfile
212: .println("Init fn=\"load-modules\" funcs=\"jk_init,jk_service\" shlib=\"<put full path to the redirector here>\"");
213: objfile.println("Init fn=\"jk_init\" worker_file=\""
214: + workersConfig.toString().replace('\\', '/')
215: + "\" log_level=\"" + jkDebug + "\" log_file=\""
216: + jkLog.toString().replace('\\', '/') + "\"");
217: objfile.println();
218: }
219:
220: protected void generateJkTail(PrintWriter objfile) {
221: objfile.println();
222: objfile
223: .println("#######################################################");
224: objfile
225: .println("# Protecting the WEB-INF and META-INF directories.");
226: objfile
227: .println("#######################################################");
228: objfile
229: .println("PathCheck fn=\"deny-existence\" path=\"*/WEB-INF/*\"");
230: objfile
231: .println("PathCheck fn=\"deny-existence\" path=\"*/META-INF/*\"");
232: objfile.println();
233:
234: objfile.println("</Object>");
235: objfile.println();
236:
237: objfile
238: .println("#######################################################");
239: objfile
240: .println("# New object to execute your servlet requests.");
241: objfile
242: .println("#######################################################");
243: objfile.println("<Object name=" + objectName + ">");
244: objfile.println("ObjectType fn=force-type type=text/html");
245: objfile.println("Service fn=\"jk_service\" worker=\""
246: + jkWorker + "\" path=\"/*\"");
247: objfile.println("</Object>");
248: objfile.println();
249: }
250:
251: // -------------------- Forward all mode --------------------
252:
253: /** Forward all requests for a context to tomcat.
254: The default.
255: */
256: protected void generateStupidMappings(Context context,
257: PrintWriter objfile) {
258: String ctxPath = context.getPath();
259: String nPath = ("".equals(ctxPath)) ? "/" : ctxPath;
260:
261: if (noRoot && "".equals(ctxPath)) {
262: log("Ignoring root context in forward-all mode ");
263: return;
264: }
265: objfile.println("<Object name=" + context.getName() + ">");
266:
267: objfile.println("NameTrans fn=\"assign-name\" from=\""
268: + ctxPath + "\" name=\"" + objectName + "\"");
269: objfile.println("NameTrans fn=\"assign-name\" from=\""
270: + ctxPath + "/*\" name=\"" + objectName + "\"");
271: objfile.println("</Object>");
272: }
273:
274: // -------------------- Netscape serves static mode --------------------
275: // This is not going to work for all apps. We fall back to stupid mode.
276:
277: protected void generateContextMappings(Context context,
278: PrintWriter objfile) {
279: String ctxPath = context.getPath();
280: String nPath = ("".equals(ctxPath)) ? "/" : ctxPath;
281:
282: if (noRoot && "".equals(ctxPath)) {
283: log("Ignoring root context in non-forward-all mode ");
284: return;
285: }
286: objfile.println("<Object name=" + context.getName() + ">");
287: // Static files will be served by Netscape
288: objfile
289: .println("#########################################################");
290: objfile.println("# Auto configuration for the " + nPath
291: + " context starts.");
292: objfile
293: .println("#########################################################");
294: objfile.println();
295:
296: // XXX Need to determine what if/how static mappings are done
297:
298: // InvokerInterceptor - it doesn't have a container,
299: // but it's implemented using a special module.
300:
301: // XXX we need to better collect all mappings
302: if (context.getLoginConfig() != null) {
303: String loginPage = context.getLoginConfig().getLoginPage();
304: if (loginPage != null) {
305: int lpos = loginPage.lastIndexOf("/");
306: String jscurl = loginPage.substring(0, lpos + 1)
307: + "j_security_check";
308: addMapping(ctxPath, jscurl, objfile);
309: }
310: }
311:
312: String[] servletMaps = context.findServletMappings();
313: for (int ii = 0; ii < servletMaps.length; ii++) {
314: addMapping(ctxPath, servletMaps[ii], objfile);
315: }
316: objfile.println("</Object>");
317: }
318:
319: /** Add a Netscape extension mapping.
320: */
321: protected boolean addMapping(String ctxPath, String ext,
322: PrintWriter objfile) {
323: if (debug > 0)
324: log("Adding extension map for " + ctxPath + "/*." + ext);
325: if (!ext.startsWith("/"))
326: ext = "/" + ext;
327: if (ext.length() > 1)
328: objfile.println("NameTrans fn=\"assign-name\" from=\""
329: + ctxPath + ext + "\" name=\"" + objectName + "\"");
330: return true;
331: }
332:
333: /** Add a fulling specified Netscape mapping.
334: */
335: protected boolean addMapping(String fullPath, PrintWriter objfile) {
336: if (debug > 0)
337: log("Adding map for " + fullPath);
338: objfile.println("NameTrans fn=\"assign-name\" from=\""
339: + fullPath + "\" name=\"" + objectName + "\"");
340: return true;
341: }
342:
343: }
|