Source code: org/apache/ajp/tomcat4/config/NSConfig.java
1 /*
2 * Copyright 1999-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.ajp.tomcat4.config;
18
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.io.IOException;
22 import java.io.PrintWriter;
23 import java.util.Date;
24
25 import org.apache.catalina.Context;
26
27
28 /**
29 Generates automatic Netscape nsapi_redirect configurations based on
30 the Tomcat server.xml settings and the war contexts
31 initialized during startup.
32 <p>
33 This config interceptor is enabled by inserting an NSConfig
34 element in the <b><ContextManager></b> tag body inside
35 the server.xml file like so:
36 <pre>
37 * < ContextManager ... >
38 * ...
39 * <<b>NSConfig</b> <i>options</i> />
40 * ...
41 * < /ContextManager >
42 </pre>
43 where <i>options</i> can include any of the following attributes:
44 <ul>
45 <li><b>configHome</b> - default parent directory for the following paths.
46 If not set, this defaults to TOMCAT_HOME. Ignored
47 whenever any of the following paths is absolute.
48 </li>
49 <li><b>objConfig</b> - path to use for writing Netscape obj.conf
50 file. If not set, defaults to
51 "conf/auto/obj.conf".</li>
52 <li><b>objectName</b> - Name of the Object to execute the requests.
53 Defaults to "servlet".</li>
54 <li><b>workersConfig</b> - path to workers.properties file used by
55 nsapi_redirect. If not set, defaults to
56 "conf/jk/workers.properties".</li>
57 <li><b>nsapiJk</b> - path to Netscape mod_jk plugin file. If not set,
58 defaults to "bin/nsapi_redirect.dll" on windows,
59 "bin/nsapi_rd.nlm" on netware, and
60 "bin/nsapi_redirector.so" everywhere else.</li>
61 <li><b>jkLog</b> - path to log file to be used by nsapi_redirect.</li>
62 <li><b>jkDebug</b> - Loglevel setting. May be debug, info, error, or emerg.
63 If not set, defaults to emerg.</li>
64 <li><b>jkWorker</b> The desired worker. Must be set to one of the workers
65 defined in the workers.properties file. "ajp12", "ajp13"
66 or "inprocess" are the workers found in the default
67 workers.properties file. If not specified, defaults
68 to "ajp13" if an Ajp13Interceptor is in use, otherwise
69 it defaults to "ajp12".</li>
70 <li><b>forwardAll</b> - If true, forward all requests to Tomcat. This helps
71 insure that all the behavior configured in the web.xml
72 file functions correctly. If false, let Netscape serve
73 static resources assuming it has been configured
74 to do so. The default is true.
75 Warning: When false, some configuration in
76 the web.xml may not be duplicated in Netscape.
77 Review the uriworkermap file to see what
78 configuration is actually being set in Netscape.</li>
79 <li><b>noRoot</b> - If true, the root context is not mapped to
80 Tomcat. If false and forwardAll is true, all requests
81 to the root context are mapped to Tomcat. If false and
82 forwardAll is false, only JSP and servlets requests to
83 the root context are mapped to Tomcat. When false,
84 to correctly serve Tomcat's root context you must also
85 modify the Home Directory setting in Netscape
86 to point to Tomcat's root context directory.
87 Otherwise some content, such as the root index.html,
88 will be served by Netscape before nsapi_redirect gets a chance
89 to claim the request and pass it to Tomcat.
90 The default is true.</li>
91 </ul>
92 <p>
93 @author Costin Manolache
94 @author Larry Isaacs
95 @author Gal Shachor
96 @author Bill Barker
97 */
98 public class NSConfig extends BaseJkConfig {
99
100 public static final String WORKERS_CONFIG = "/conf/jk/workers.properties";
101 public static final String NS_CONFIG = "/conf/auto/obj.conf";
102 public static final String NSAPI_LOG_LOCATION = "/logs/nsapi_redirect.log";
103 /** default location of nsapi plug-in. */
104 public static final String NSAPI_REDIRECTOR;
105
106 //set up some defaults based on OS type
107 static{
108 String os = System.getProperty("os.name").toLowerCase();
109 if(os.indexOf("windows")>=0){
110 NSAPI_REDIRECTOR = "bin/nsapi_redirect.dll";
111 }else if(os.indexOf("netware")>=0){
112 NSAPI_REDIRECTOR = "bin/nsapi_rd.nlm";
113 }else{
114 NSAPI_REDIRECTOR = "bin/nsapi_redirector.so";
115 }
116 }
117
118 private File objConfig = null;
119 private File nsapiJk = null;
120 private String objectName = "servlet";
121
122 public NSConfig()
123 {
124 }
125
126 //-------------------- Properties --------------------
127
128 /**
129 set the path to the output file for the auto-generated
130 isapi_redirect registry file. If this path is relative
131 then getRegConfig() will resolve it absolutely against
132 the getConfigHome() path.
133 <p>
134 @param path String path to a file
135 */
136 public void setObjConfig(String path) {
137 objConfig= (path==null)?null:new File(path);
138 }
139
140 /**
141 set the path to the nsapi plugin module
142 @param path String path to a file
143 */
144 public void setNsapiJk(String path) {
145 nsapiJk=( path==null?null:new File(path));
146 }
147
148 /**
149 Set the name for the Object that implements the
150 jk_service call.
151 @param name Name of the obj.conf Object
152 */
153 public void setObjectName(String name) {
154 objectName = name;
155 }
156
157 // -------------------- Initialize/guess defaults --------------------
158
159 /** Initialize defaults for properties that are not set
160 explicitely
161 */
162 protected void initProperties() {
163 super.initProperties();
164
165 objConfig=getConfigFile( objConfig, configHome, NS_CONFIG);
166 workersConfig=getConfigFile( workersConfig, configHome, WORKERS_CONFIG);
167
168 if( nsapiJk == null )
169 nsapiJk=new File(NSAPI_REDIRECTOR);
170 else
171 nsapiJk =getConfigFile( nsapiJk, configHome, 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 protected boolean generateJkHead(PrintWriter mod_jk) {
181 log("Generating netscape web server config = "+objConfig );
182
183 generateNsapiHead( mod_jk );
184
185 mod_jk.println("<Object name=default>");
186 return true;
187 }
188
189 private void generateNsapiHead(PrintWriter objfile)
190 {
191 objfile.println("###################################################################");
192 objfile.println("# Auto generated configuration. Dated: " + new Date());
193 objfile.println("###################################################################");
194 objfile.println();
195
196 objfile.println("#");
197 objfile.println("# You will need to merge the content of this file with your ");
198 objfile.println("# regular obj.conf and then restart (=stop + start) your Netscape server. ");
199 objfile.println("#");
200 objfile.println();
201
202 objfile.println("#");
203 objfile.println("# Loading the redirector into your server");
204 objfile.println("#");
205 objfile.println();
206 objfile.println("Init fn=\"load-modules\" funcs=\"jk_init,jk_service\" shlib=\"<put full path to the redirector here>\"");
207 objfile.println("Init fn=\"jk_init\" worker_file=\"" +
208 workersConfig.toString().replace('\\', '/') +
209 "\" log_level=\"" + jkDebug + "\" log_file=\"" +
210 jkLog.toString().replace('\\', '/') +
211 "\"");
212 objfile.println();
213 }
214
215 protected void generateJkTail(PrintWriter objfile)
216 {
217 objfile.println();
218 objfile.println("#######################################################");
219 objfile.println("# Protecting the WEB-INF and META-INF directories.");
220 objfile.println("#######################################################");
221 objfile.println("PathCheck fn=\"deny-existence\" path=\"*/WEB-INF/*\"");
222 objfile.println("PathCheck fn=\"deny-existence\" path=\"*/META-INF/*\"");
223 objfile.println();
224
225 objfile.println("</Object>");
226 objfile.println();
227
228 objfile.println("#######################################################");
229 objfile.println("# New object to execute your servlet requests.");
230 objfile.println("#######################################################");
231 objfile.println("<Object name=" + objectName + ">");
232 objfile.println("ObjectType fn=force-type type=text/html");
233 objfile.println("Service fn=\"jk_service\" worker=\""+ jkWorker + "\" path=\"/*\"");
234 objfile.println("</Object>");
235 objfile.println();
236 }
237
238 // -------------------- Forward all mode --------------------
239
240 /** Forward all requests for a context to tomcat.
241 The default.
242 */
243 protected void generateStupidMappings(Context context, PrintWriter objfile )
244 {
245 String ctxPath = context.getPath();
246 String nPath=("".equals(ctxPath)) ? "/" : ctxPath;
247
248 if( noRoot && "".equals(ctxPath) ) {
249 log("Ignoring root context in forward-all mode ");
250 return;
251 }
252 objfile.println("<Object name=" + context.getName() + ">");
253
254 objfile.println("NameTrans fn=\"assign-name\" from=\"" + ctxPath + "\" name=\"" + objectName + "\"");
255 objfile.println("NameTrans fn=\"assign-name\" from=\"" + ctxPath + "/*\" name=\"" + objectName + "\"");
256 objfile.println("</Object>");
257 }
258
259
260 // -------------------- Netscape serves static mode --------------------
261 // This is not going to work for all apps. We fall back to stupid mode.
262
263 protected void generateContextMappings(Context context, PrintWriter objfile )
264 {
265 String ctxPath = context.getPath();
266 String nPath=("".equals(ctxPath)) ? "/" : ctxPath;
267
268 if( noRoot && "".equals(ctxPath) ) {
269 log("Ignoring root context in non-forward-all mode ");
270 return;
271 }
272 objfile.println("<Object name=" + context.getName() + ">");
273 // Static files will be served by Netscape
274 objfile.println("#########################################################");
275 objfile.println("# Auto configuration for the " + nPath + " context starts.");
276 objfile.println("#########################################################");
277 objfile.println();
278
279 // XXX Need to determine what if/how static mappings are done
280
281 // InvokerInterceptor - it doesn't have a container,
282 // but it's implemented using a special module.
283
284 // XXX we need to better collect all mappings
285 if(context.getLoginConfig() != null) {
286 String loginPage = context.getLoginConfig().getLoginPage();
287 if(loginPage != null) {
288 int lpos = loginPage.lastIndexOf("/");
289 String jscurl = loginPage.substring(0,lpos+1) + "j_security_check";
290 addMapping( ctxPath, jscurl, objfile);
291 }
292 }
293
294 String [] servletMaps=context.findServletMappings();
295 for(int ii=0; ii < servletMaps.length; ii++) {
296 addMapping( ctxPath , servletMaps[ii] , objfile );
297 }
298 objfile.println("</Object>");
299 }
300
301 /** Add a Netscape extension mapping.
302 */
303 protected boolean addMapping( String ctxPath, String ext,
304 PrintWriter objfile )
305 {
306 if( debug > 0 )
307 log( "Adding extension map for " + ctxPath + "/*." + ext );
308 if(! ext.startsWith("/") )
309 ext = "/" + ext;
310 if(ext.length() > 1)
311 objfile.println("NameTrans fn=\"assign-name\" from=\"" +
312 ctxPath + ext + "\" name=\"" + objectName + "\"");
313 return true;
314 }
315
316 /** Add a fulling specified Netscape mapping.
317 */
318 protected boolean addMapping( String fullPath, PrintWriter objfile ) {
319 if( debug > 0 )
320 log( "Adding map for " + fullPath );
321 objfile.println("NameTrans fn=\"assign-name\" from=\"" +
322 fullPath + "\" name=\"" + objectName + "\"");
323 return true;
324 }
325
326 }