Source code: org/apache/ajp/tomcat4/config/IISConfig.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 IIS isapi_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 IISConfig
34 element in the <b><ContextManager></b> tag body inside
35 the server.xml file like so:
36 <pre>
37 * < ContextManager ... >
38 * ...
39 * <<b>IISConfig</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>regConfig</b> - path to use for writing IIS isapi_redirect registry
50 file. If not set, defaults to
51 "conf/auto/iis_redirect.reg".</li>
52 <li><b>workersConfig</b> - path to workers.properties file used by
53 isapi_redirect. If not set, defaults to
54 "conf/jk/workers.properties".</li>
55 <li><b>uriConfig</b> - path to use for writing IIS isapi_redirect uriworkermap
56 file. If not set, defaults to
57 "conf/auto/uriworkermap.properties".</li>
58 <li><b>jkLog</b> - path to log file to be used by isapi_redirect.</li>
59 <li><b>jkDebug</b> - Loglevel setting. May be debug, info, error, or emerg.
60 If not set, defaults to emerg.</li>
61 <li><b>jkWorker</b> The desired worker. Must be set to one of the workers
62 defined in the workers.properties file. "ajp12", "ajp13"
63 or "inprocess" are the workers found in the default
64 workers.properties file. If not specified, defaults
65 to "ajp13" if an Ajp13Interceptor is in use, otherwise
66 it defaults to "ajp12".</li>
67 <li><b>forwardAll</b> - If true, forward all requests to Tomcat. This helps
68 insure that all the behavior configured in the web.xml
69 file functions correctly. If false, let IIS serve
70 static resources assuming it has been configured
71 to do so. The default is true.
72 Warning: When false, some configuration in
73 the web.xml may not be duplicated in IIS.
74 Review the uriworkermap file to see what
75 configuration is actually being set in IIS.</li>
76 <li><b>noRoot</b> - If true, the root context is not mapped to
77 Tomcat. If false and forwardAll is true, all requests
78 to the root context are mapped to Tomcat. If false and
79 forwardAll is false, only JSP and servlets requests to
80 the root context are mapped to Tomcat. When false,
81 to correctly serve Tomcat's root context you must also
82 modify the Home Directory setting in IIS
83 to point to Tomcat's root context directory.
84 Otherwise some content, such as the root index.html,
85 will be served by IIS before isapi_redirect gets a chance
86 to claim the request and pass it to Tomcat.
87 The default is true.</li>
88 </ul>
89 <p>
90 @author Costin Manolache
91 @author Larry Isaacs
92 @author Gal Shachor
93 @author Bill Barker
94 */
95 public class IISConfig extends BaseJkConfig {
96
97 public static final String WORKERS_CONFIG = "/conf/jk/workers.properties";
98 public static final String URI_WORKERS_MAP_CONFIG = "/conf/auto/uriworkermap.properties";
99 public static final String ISAPI_LOG_LOCATION = "/logs/iis_redirect.log";
100 public static final String ISAPI_REG_FILE = "/conf/auto/iis_redirect.reg";
101
102 private File regConfig = null;
103 private File uriConfig = null;
104
105 public IISConfig()
106 {
107 }
108
109 //-------------------- Properties --------------------
110
111 /**
112 set the path to the output file for the auto-generated
113 isapi_redirect registry file. If this path is relative
114 then getRegConfig() will resolve it absolutely against
115 the getConfigHome() path.
116 <p>
117 @param path String path to a file
118 */
119 public void setRegConfig(String path){
120 regConfig= (path==null)?null:new File(path);
121 }
122
123 /**
124 set a path to the uriworkermap.properties file.
125 @param path String path to uriworkermap.properties file
126 */
127 public void setUriConfig(String path){
128 uriConfig= (path==null?null:new File(path));
129 }
130
131 // -------------------- Initialize/guess defaults --------------------
132
133 /** Initialize defaults for properties that are not set
134 explicitely
135 */
136 protected void initProperties() {
137 super.initProperties();
138
139 regConfig=getConfigFile( regConfig, configHome, ISAPI_REG_FILE);
140 workersConfig=getConfigFile( workersConfig, configHome, WORKERS_CONFIG);
141 uriConfig=getConfigFile( uriConfig, configHome, URI_WORKERS_MAP_CONFIG);
142 jkLog=getConfigFile( jkLog, configHome, ISAPI_LOG_LOCATION);
143 }
144
145 // -------------------- Generate config --------------------
146
147 protected PrintWriter getWriter() throws IOException {
148 String abUriConfig = uriConfig.getAbsolutePath();
149 return new PrintWriter(new FileWriter(abUriConfig,append));
150 }
151 protected boolean generateJkHead(PrintWriter mod_jk) {
152 try {
153 PrintWriter regfile = new PrintWriter(new FileWriter(regConfig));
154 log("Generating IIS registry file = "+regConfig );
155 generateRegistrySettings(regfile);
156 regfile.close();
157 } catch(IOException iex) {
158 log("Unable to generate registry file " +regConfig);
159 return false;
160 }
161 log("Generating IIS URI worker map file = "+uriConfig );
162 generateUriWorkerHeader(mod_jk);
163 return true;
164 }
165
166 // -------------------- Config sections --------------------
167
168 /** Writes the registry settings required by the IIS connector
169 */
170 private void generateRegistrySettings(PrintWriter regfile)
171 {
172 regfile.println("REGEDIT4");
173 regfile.println();
174 regfile.println("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Apache Software Foundation\\Jakarta Isapi Redirector\\1.0]");
175 regfile.println("\"extension_uri\"=\"/jakarta/isapi_redirect.dll\"");
176 regfile.println("\"log_file\"=\"" + dubleSlash(jkLog.toString()) +"\"");
177 regfile.println("\"log_level\"=\"" + jkDebug + "\"");
178 regfile.println("\"worker_file\"=\"" + dubleSlash(workersConfig.toString()) +"\"");
179 regfile.println("\"worker_mount_file\"=\"" + dubleSlash(uriConfig.toString()) +"\"");
180 }
181
182 /** Writes the header information to the uriworkermap file
183 */
184 private void generateUriWorkerHeader(PrintWriter uri_worker)
185 {
186 uri_worker.println("###################################################################");
187 uri_worker.println("# Auto generated configuration. Dated: " + new Date());
188 uri_worker.println("###################################################################");
189 uri_worker.println();
190
191 uri_worker.println("#");
192 uri_worker.println("# Default worker to be used through our mappings");
193 uri_worker.println("#");
194 uri_worker.println("default.worker=" + jkWorker);
195 uri_worker.println();
196 }
197
198 /** Forward all requests for a context to tomcat.
199 The default.
200 */
201 protected void generateStupidMappings(Context context, PrintWriter uri_worker )
202 {
203 String ctxPath = context.getPath();
204 String nPath=("".equals(ctxPath)) ? "/" : ctxPath;
205
206 if( noRoot && "".equals(ctxPath) ) {
207 log("Ignoring root context in forward-all mode ");
208 return;
209 }
210
211 // map all requests for this context to Tomcat
212 uri_worker.println(nPath +"=$(default.worker)");
213 if( "".equals(ctxPath) ) {
214 uri_worker.println(nPath +"*=$(default.worker)");
215 uri_worker.println(
216 "# Note: To correctly serve the Tomcat's root context, IIS's Home Directory must");
217 uri_worker.println(
218 "# must be set to: \"" + getAbsoluteDocBase(context) + "\"");
219 }
220 else
221 uri_worker.println(nPath +"/*=$(default.worker)");
222 }
223
224 protected void generateContextMappings(Context context, PrintWriter uri_worker )
225 {
226 String ctxPath = context.getPath();
227 String nPath=("".equals(ctxPath)) ? "/" : ctxPath;
228
229 if( noRoot && "".equals(ctxPath) ) {
230 log("Ignoring root context in forward-all mode ");
231 return;
232 }
233
234 // Static files will be served by IIS
235 uri_worker.println();
236 uri_worker.println("#########################################################");
237 uri_worker.println("# Auto configuration for the " + nPath + " context.");
238 uri_worker.println("#########################################################");
239 uri_worker.println();
240
241 // Static mappings are not set in uriworkermap, but must be set with IIS admin.
242
243 // InvokerInterceptor - it doesn't have a container,
244 // but it's implemented using a special module.
245
246 // XXX we need to better collect all mappings
247
248 if(context.getLoginConfig() != null) {
249 String loginPage = context.getLoginConfig().getLoginPage();
250 if(loginPage != null) {
251 int lpos = loginPage.lastIndexOf("/");
252 String jscurl = loginPage.substring(0,lpos+1) + "j_security_check";
253 addMapping( ctxPath, jscurl, uri_worker);
254 }
255 }
256 String [] servletMaps=context.findServletMappings();
257 for( int ii=0; ii < servletMaps.length ; ii++) {
258 addMapping( ctxPath , servletMaps[ii] , uri_worker );
259 }
260 }
261
262 /** Add an IIS extension mapping.
263 */
264 protected boolean addMapping( String ctxPath, String ext,
265 PrintWriter uri_worker )
266 {
267 if( debug > 0 )
268 log( "Adding extension map for " + ctxPath + "/*." + ext );
269 if(! ext.startsWith("/") )
270 ext = "/" + ext;
271 if(ext.length() > 1)
272 uri_worker.println(ctxPath + "/*." + ext + "=$(default.worker)");
273 return true;
274 }
275
276 /** Add a fulling specified IIS mapping.
277 */
278 protected boolean addMapping( String fullPath, PrintWriter uri_worker ) {
279 if( debug > 0 )
280 log( "Adding map for " + fullPath );
281 uri_worker.println(fullPath + "=$(default.worker)" );
282 return true;
283 }
284
285 // -------------------- Utils --------------------
286
287 private String dubleSlash(String in)
288 {
289 StringBuffer sb = new StringBuffer();
290
291 for(int i = 0 ; i < in.length() ; i++) {
292 char ch = in.charAt(i);
293 if('\\' == ch) {
294 sb.append("\\\\");
295 } else {
296 sb.append(ch);
297 }
298 }
299
300 return sb.toString();
301 }
302
303 }