1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.services.webpage;
18
19
20 import java.io.IOException;
21
22
23 import java.util.Collection;
24 import java.util.Iterator;
25
26
27 import javax.servlet.ServletException;
28 import javax.servlet.ServletConfig;
29 import javax.servlet.http.HttpServlet;
30 import javax.servlet.http.HttpSession;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34
35 import java.net.URL;
36 import java.util.HashMap;
37 import java.net.MalformedURLException;
38
39 import org.apache.log4j.Logger;
40
41 /***
42 *
43 * <p>This is the default implementation of the <code>WebPageService</code> interface.</p>
44 *
45 * <p>
46 * It is a service that provides Web Page facade and delegation
47 * services for clients to transparently access resources existing on web
48 * pages from requests originating from the portal server.</p>
49 *
50 * <p>Since the WebPage service is giving the appearance of a single session to
51 * the client, the service needs to manage the synchronization of sessions,
52 * including single-sign-on, and security authorization permissions between the
53 * the portal server and one or more sites.</p>
54 *
55 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
56 * @version $Id: JetspeedWebPageService.java,v 1.4 2004/02/23 03:46:26 jford Exp $
57 */
58
59 public class JetspeedWebPageService
60 implements WebPageService
61 {
62
63 public final static String SESSION_MAP = "wps.SessionMap";
64 public final static String URL_SESSION_MAP = "wps.URLSessionMap";
65
66 public final static String INIT_PROPERTIES_PARAM = "properties";
67
68 /***
69 * service state
70 *
71 */
72
73
74 private String host = null;
75
76
77
78 private HashMap sites = new HashMap();
79
80
81
82
83 private HashMap sessions = new HashMap();
84
85
86 private boolean init = false;
87
88
89 static Logger log = Logger.getLogger(JetspeedWebPageService.class);
90
91
92 private String lastError = "Jetspeed WebPage Service has not been initialized.";
93
94 /***
95 * The primary method invoked when the a Jetspeed GET is executed.
96 *
97 * @param servlet the Servlet.
98 * @param request Servlet request.
99 * @param response Servlet response.
100 * @exception IOException a servlet exception.
101 * @exception ServletException a servlet exception.
102 */
103 public void get(HttpServlet servlet,
104 HttpServletRequest request,
105 HttpServletResponse response)
106 throws ServletException, IOException
107 {
108 ProxyRunData rundata = new ProxyRunData(servlet, request, response, false);
109 dispatch(rundata);
110 }
111
112 /***
113 * The primary method invoked when the a Jetspeed POST is executed.
114 *
115 * @param servlet the Servlet.
116 * @param request Servlet request.
117 * @param response Servlet response.
118 * @exception IOException a servlet exception.
119 * @exception ServletException a servlet exception.
120 */
121 public void post(HttpServlet servlet,
122 HttpServletRequest request,
123 HttpServletResponse response)
124 throws ServletException, IOException
125 {
126 ProxyRunData rundata = new ProxyRunData(servlet, request, response, true);
127 dispatch(rundata);
128 }
129
130
131 /***
132 * The common dispatcher for both GETs and PUTs
133 *
134 * @param data the request specific state.
135 * @exception IOException a servlet exception.
136 * @exception ServletException a servlet exception.
137 */
138 private void dispatch(ProxyRunData data)
139 throws ServletException, IOException
140 {
141
142
143
144
145
146 getHost(data.getRequest());
147
148
149
150
151 Configuration config = Configuration.getInstance();
152 String sid = data.getRequest().getParameter(config.getSID());
153 String url = data.getRequest().getParameter(config.getURL());
154
155 if (null == sid)
156 {
157 if (null == url)
158 {
159 throw new ServletException("Bad Request. No proxy-parameters passed in request.");
160 }
161 proxyByURL(url, data);
162 return;
163 }
164
165
166
167
168
169
170 Site site = getSite(sid);
171 if (null == site)
172 {
173
174 throw new ServletException("The Requested Site ID is currently not configured on this system: " + sid);
175 }
176
177
178
179
180
181 if (site.getStatus() != Configuration.STATUS_ONLINE)
182 {
183 throw new ServletException("The Requested Site ("
184 + site.getURL()
185 + ") is not available. Status = "
186 + WebPageHelper.getAvailabilityStatus(site.getStatus()) );
187 }
188
189
190
191
192 String resource = getResourcePath(site.getURL(), data.getRequest());
193
194 boolean loggedOn = true;
195
196
197
198
199
200 HttpSession session = data.getRequest().getSession(false);
201 if (null == session)
202 {
203 session = data.getRequest().getSession(true);
204 }
205
206
207
208
209 String sessionID = session.getId();
210 SessionMap smap = (SessionMap)sessions.get(sessionID);
211 SiteSession jss = null;
212 if (null == smap)
213 {
214
215
216
217
218
219
220
221
222
223
224 String username = "";
225 smap = new SessionMap(sessionID, username);
226
227
228
229 session.setAttribute(SESSION_MAP, smap);
230
231 sessions.put(sessionID, smap);
232
233
234 jss = new JetspeedSiteSession(site, this.host, username);
235
236
237 smap.put(site.getURL(), jss);
238
239
240 loggedOn = jss.logon(data);
241
242 } else
243 {
244
245 jss = (JetspeedSiteSession)smap.get(site.getURL());
246 if (null == jss)
247 {
248
249
250
251
252
253
254
255
256
257
258
259 String username = "";
260 jss = new JetspeedSiteSession(site, this.host, username);
261 smap.put(site.getURL(), jss);
262
263
264 loggedOn = jss.logon(data);
265 }
266 }
267 if (loggedOn)
268 {
269
270 if (data.getRequest().getParameter("logon-test") != null)
271 return;
272
273 if (WebPageCache.isCacheableResource(resource))
274 {
275 if (WebPageCache.getResourceFromCache(resource, site.getID(), site.getURL(), this.host, data))
276 {
277 smap.incCacheCount();
278 jss.incCacheCount();
279 }
280 else
281 {
282 smap.incHitCount();
283 jss.incHitCount();
284 }
285 return;
286 }
287
288 smap.incHitCount();
289 jss.incHitCount();
290 jss.proxy(resource, data);
291 }
292 }
293
294 /***
295 * Builds the proxy url which is used when rewriting other URLs
296 *
297 *
298 * @param req Servlet request.
299 */
300 private void getHost(HttpServletRequest request)
301 {
302
303
304
305 if (null != this.host)
306 return;
307
308 StringBuffer root = new StringBuffer();
309 String scheme = request.getScheme();
310 root.append(scheme);
311 root.append( "://");
312 int port = request.getServerPort();
313
314 String hostname = request.getServerName();
315 String ip = WebPageHelper.getIP(hostname);
316 if (null == ip)
317 root.append(hostname);
318 else
319 root.append(ip);
320
321 if ( (port > 0) &&
322 ((scheme.equals("http") && port != 80) ||
323 (scheme.equals("https") && port != 443)
324 )
325 )
326 {
327 root.append(":");
328 root.append(port);
329 }
330 root.append( request.getServletPath() );
331 this.host = root.toString();
332 }
333
334 /***
335 * Given a Site id, maps to base URL for that site and returns the Site object
336 *
337 *
338 * @param sid the string Site ID
339 * @return the Site object.
340 */
341 public Site getSite(String sid) throws ServletException
342 {
343 return(Site)sites.get(sid);
344 }
345
346 /***
347 * Creates the full path the requested resource on the site from a relative path in request.
348 *
349 * @param url the base url for the site.
350 * @param request the Servlet request.
351 * @return the full path to the resource.
352 */
353 public String getResourcePath(String url, HttpServletRequest request)
354 {
355 String path = request.getParameter(Configuration.getInstance().getPath());
356 if (path == null)
357 return "";
358
359 String fullPath = WebPageHelper.concatURLs(url, path);
360
361 return fullPath.replace('@', '&');
362 }
363
364
365 /***
366 * Given a URL, begin a Jetspeed session with that host
367 * It is here for future use.
368 *
369 * @param url the URL of the host to proxy.
370 * @param data the runData
371 * @return a new session
372 */
373 private SiteSession proxyByURL(String url,
374 ProxyRunData data)
375 throws ServletException, IOException
376 {
377 String newURL = url.replace('@', '&');
378 String base = getTargetBase(newURL);
379
380
381
382
383 HttpSession session = data.getRequest().getSession(false);
384 if (null == session)
385 {
386 session = data.getRequest().getSession(true);
387 }
388
389 String sessionID = session.getId();
390 SessionMap smap = (SessionMap)sessions.get(sessionID);
391
392 SiteSession pxSession = null;
393 if (null == smap)
394 {
395
396 smap = new SessionMap(sessionID, "NA");
397
398 session.setAttribute(URL_SESSION_MAP, smap);
399 sessions.put(sessionID, smap);
400
401 Site site = new SecuredSite(base, base);
402 pxSession = new JetspeedSiteSession(site, base, this.host);
403 smap.put(base, pxSession);
404 }
405 else
406 {
407 pxSession = (JetspeedSiteSession)smap.get(base);
408 if (null == pxSession)
409 {
410 Site site = new SecuredSite(base, base);
411 pxSession = new JetspeedSiteSession(site, base, this.host);
412 smap.put(base, pxSession);
413 }
414 }
415
416 if (WebPageCache.isCacheableResource(newURL))
417 {
418
419 if (WebPageCache.getResourceFromCache(newURL, -1, base, this.host, data))
420 {
421 smap.incCacheCount();
422 pxSession.incCacheCount();
423 }
424 else
425 {
426 smap.incHitCount();
427 pxSession.incHitCount();
428 }
429 return (JetspeedSiteSession)pxSession;
430 }
431
432 smap.incHitCount();
433 pxSession.incHitCount();
434 pxSession.proxy(newURL, data);
435 return(JetspeedSiteSession)pxSession;
436 }
437
438 /***
439 * Maps a full URL path to a resource to a base path
440 * given: http://localhost:8080/jetspeed/search/index.html
441 * returns: http://localhost:8080/jetspeed/
442 *
443 * @param url the full URL of the resource.
444 * @return the base host application string
445 */
446 public String getTargetBase(String url) throws ServletException
447 {
448 try
449 {
450 URL u = new URL(url);
451 StringBuffer base = new StringBuffer();
452 String protocol = u.getProtocol();
453 base.append(protocol);
454 base.append( "://");
455 int port = u.getPort();
456 base.append(u.getHost());
457 if ( (port > 0) &&
458 ((protocol.equals("http") && port != 80) ||
459 (protocol.equals("https") && port != 443)
460 )
461 )
462 {
463 base.append(":");
464 base.append(port);
465 }
466
467
468
469 String path = u.getFile();
470
471 if (null != path)
472 {
473
474 int dot = path.lastIndexOf('.');
475 int slash = path.lastIndexOf('/');
476 if (dot > slash && slash != -1)
477 {
478 path = path.substring(0, slash);
479 }
480
481
482 base.append(path);
483
484 if ('/' != base.charAt(base.length()-1))
485 base.append('/');
486 } else
487 base.append("/");
488
489 return base.toString();
490 } catch (MalformedURLException e)
491 {
492 throw new ServletException(e.toString());
493 }
494 }
495
496
497 /***
498 * One time initialization of the proxy service
499 *
500 * @param config the servlet configuration.
501 * @exception IOException a servlet exception.
502 * @exception ServletException a servlet exception.
503 */
504 public boolean init(ServletConfig config)
505 throws ServletException, IOException
506 {
507
508 String paramFile = config.getInitParameter(INIT_PROPERTIES_PARAM);
509 if (null == paramFile)
510 {
511 lastError = "Jetspeed HTTP Proxy Init Property Not Found:" + INIT_PROPERTIES_PARAM;
512 log.error(lastError);
513 return false;
514 }
515
516 String fullPath = config.getServletContext().getRealPath(paramFile);
517
518 Configuration pc = Configuration.getInitialInstance(fullPath);
519 if (null == pc)
520 {
521 return false;
522 }
523
524 lastError = "";
525 init = true;
526 return true;
527 }
528
529 /***
530 * Returns true if the service was initialized successfully.
531 *
532 * @retun true if the service was initialized successfully.
533 */
534 public boolean isInit()
535 {
536 return init;
537 }
538
539 /***
540 * One time de-initialization of the proxy service
541 *
542 */
543 public void destroy()
544 {
545 try
546 {
547
548
549
550 Iterator it = sessions.values().iterator();
551 while (it.hasNext())
552 {
553 SessionMap map = (SessionMap)it.next();
554 Iterator itElements = map.values().iterator();
555 while (itElements.hasNext())
556 {
557 SiteSession has = (SiteSession)itElements.next();
558 try
559 {
560 has.logout(null);
561 }
562 catch (Exception e)
563 {
564
565 log.error("Shutdown-Logout of Session: " + e);
566 }
567 }
568 }
569
570 } catch ( Exception ex )
571 {
572 log.error( ex );
573 }
574 }
575
576 /***
577 * Returns a snapshot collection of all the active and inactive sessions.
578 *
579 * @return the collection of sessions.
580 */
581 public Collection getSessions()
582 {
583 return sessions.values();
584 }
585
586 /***
587 * Returns a session, give a string id key identifying that session.
588 *
589 * @param id The ID of the session.
590 * @return The corresponding session.
591 */
592 public SessionMap getSession(String id)
593 {
594 return (SessionMap)sessions.get(id);
595 }
596
597 /***
598 * Returns a snapshot collection of all the managed sites in the system.
599 *
600 * @return the collection of sites.
601 */
602 public Collection getSites()
603 {
604 return sites.values();
605 }
606
607
608 /***
609 * Returns the error string from failed initialized.
610 *
611 * @return the error string from last error.
612 */
613 public String getErrorString()
614 {
615 return lastError;
616 }
617
618
619 }
620
621
622
623
624