1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.eclipse.jetty.server.session;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.ObjectInputStream;
27 import java.io.ObjectOutputStream;
28 import java.sql.Connection;
29 import java.sql.PreparedStatement;
30 import java.sql.ResultSet;
31 import java.sql.SQLException;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.concurrent.atomic.AtomicReference;
38
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpSessionEvent;
41 import javax.servlet.http.HttpSessionListener;
42
43 import org.eclipse.jetty.server.SessionIdManager;
44 import org.eclipse.jetty.server.handler.ContextHandler;
45 import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
46 import org.eclipse.jetty.util.log.Log;
47 import org.eclipse.jetty.util.log.Logger;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class JDBCSessionManager extends AbstractSessionManager
74 {
75 private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
76
77 private ConcurrentHashMap<String, AbstractSession> _sessions;
78 protected JDBCSessionIdManager _jdbcSessionIdMgr = null;
79 protected long _saveIntervalSec = 60;
80
81
82
83
84
85
86
87
88
89 public class Session extends AbstractSession
90 {
91 private static final long serialVersionUID = 5208464051134226143L;
92
93
94
95
96 private boolean _dirty=false;
97
98
99
100
101
102 private long _cookieSet;
103
104
105
106
107
108 private long _expiryTime;
109
110
111
112
113
114 private long _lastSaved;
115
116
117
118
119
120 private String _lastNode;
121
122
123
124
125
126 private String _virtualHost;
127
128
129
130
131
132 private String _rowId;
133
134
135
136
137
138 private String _canonicalContext;
139
140
141
142
143
144
145
146 protected Session (HttpServletRequest request)
147 {
148 super(JDBCSessionManager.this,request);
149 int maxInterval=getMaxInactiveInterval();
150 _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
151 _virtualHost = JDBCSessionManager.getVirtualHost(_context);
152 _canonicalContext = canonicalize(_context.getContextPath());
153 _lastNode = getSessionIdManager().getWorkerName();
154 }
155
156
157
158
159
160
161
162
163
164 protected Session (String sessionId, String rowId, long created, long accessed, long maxInterval)
165 {
166 super(JDBCSessionManager.this, created, accessed, sessionId);
167 _rowId = rowId;
168 super.setMaxInactiveInterval((int)maxInterval);
169 _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
170 }
171
172
173 protected synchronized String getRowId()
174 {
175 return _rowId;
176 }
177
178 protected synchronized void setRowId(String rowId)
179 {
180 _rowId = rowId;
181 }
182
183 public synchronized void setVirtualHost (String vhost)
184 {
185 _virtualHost=vhost;
186 }
187
188 public synchronized String getVirtualHost ()
189 {
190 return _virtualHost;
191 }
192
193 public synchronized long getLastSaved ()
194 {
195 return _lastSaved;
196 }
197
198 public synchronized void setLastSaved (long time)
199 {
200 _lastSaved=time;
201 }
202
203 public synchronized void setExpiryTime (long time)
204 {
205 _expiryTime=time;
206 }
207
208 public synchronized long getExpiryTime ()
209 {
210 return _expiryTime;
211 }
212
213
214 public synchronized void setCanonicalContext(String str)
215 {
216 _canonicalContext=str;
217 }
218
219 public synchronized String getCanonicalContext ()
220 {
221 return _canonicalContext;
222 }
223
224 public void setCookieSet (long ms)
225 {
226 _cookieSet = ms;
227 }
228
229 public synchronized long getCookieSet ()
230 {
231 return _cookieSet;
232 }
233
234 public synchronized void setLastNode (String node)
235 {
236 _lastNode=node;
237 }
238
239 public synchronized String getLastNode ()
240 {
241 return _lastNode;
242 }
243
244 @Override
245 public void setAttribute (String name, Object value)
246 {
247 _dirty = (updateAttribute(name, value) || _dirty);
248 }
249
250 @Override
251 public void removeAttribute (String name)
252 {
253 super.removeAttribute(name);
254 _dirty=true;
255 }
256
257 @Override
258 protected void cookieSet()
259 {
260 _cookieSet = getAccessed();
261 }
262
263
264
265
266
267
268
269 @Override
270 protected boolean access(long time)
271 {
272 synchronized (this)
273 {
274 if (super.access(time))
275 {
276 int maxInterval=getMaxInactiveInterval();
277 _expiryTime = (maxInterval <= 0 ? 0 : (time + maxInterval*1000L));
278 return true;
279 }
280 return false;
281 }
282 }
283
284
285
286
287
288
289
290
291
292 @Override
293 public void setMaxInactiveInterval(int secs)
294 {
295 synchronized (this)
296 {
297 super.setMaxInactiveInterval(secs);
298 int maxInterval=getMaxInactiveInterval();
299 _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
300
301 try
302 {
303 updateSessionAccessTime(this);
304 }
305 catch (Exception e)
306 {
307 LOG.warn("Problem saving changed max idle time for session "+ this, e);
308 }
309 }
310 }
311
312
313
314
315
316
317 @Override
318 protected void complete()
319 {
320 synchronized (this)
321 {
322 super.complete();
323 try
324 {
325 if (isValid())
326 {
327 if (_dirty)
328 {
329
330
331 willPassivate();
332 updateSession(this);
333 didActivate();
334 }
335 else if ((getAccessed() - _lastSaved) >= (getSaveInterval() * 1000L))
336 {
337 updateSessionAccessTime(this);
338 }
339 }
340 }
341 catch (Exception e)
342 {
343 LOG.warn("Problem persisting changed session data id="+getId(), e);
344 }
345 finally
346 {
347 _dirty=false;
348 }
349 }
350 }
351
352 protected void save() throws Exception
353 {
354 synchronized (this)
355 {
356 try
357 {
358 updateSession(this);
359 }
360 finally
361 {
362 _dirty = false;
363 }
364 }
365 }
366
367 @Override
368 protected void timeout() throws IllegalStateException
369 {
370 if (LOG.isDebugEnabled())
371 LOG.debug("Timing out session id="+getClusterId());
372 super.timeout();
373 }
374
375
376 @Override
377 public String toString ()
378 {
379 return "Session rowId="+_rowId+",id="+getId()+",lastNode="+_lastNode+
380 ",created="+getCreationTime()+",accessed="+getAccessed()+
381 ",lastAccessed="+getLastAccessedTime()+",cookieSet="+_cookieSet+
382 ",maxInterval="+getMaxInactiveInterval()+",lastSaved="+_lastSaved+",expiry="+_expiryTime;
383 }
384 }
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 public void setSaveInterval (long sec)
408 {
409 _saveIntervalSec=sec;
410 }
411
412 public long getSaveInterval ()
413 {
414 return _saveIntervalSec;
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 public void cacheInvalidate (Session session)
431 {
432
433 }
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452 @Override
453 public Session getSession(String idInCluster)
454 {
455 Session session = null;
456 Session memSession = (Session)_sessions.get(idInCluster);
457
458 synchronized (this)
459 {
460
461
462
463
464
465
466
467
468
469 long now = System.currentTimeMillis();
470 if (LOG.isDebugEnabled())
471 {
472 if (memSession==null)
473 LOG.debug("getSession("+idInCluster+"): not in session map,"+
474 " now="+now+
475 " lastSaved="+(memSession==null?0:memSession._lastSaved)+
476 " interval="+(_saveIntervalSec * 1000L));
477 else
478 LOG.debug("getSession("+idInCluster+"): in session map, "+
479 " now="+now+
480 " lastSaved="+(memSession==null?0:memSession._lastSaved)+
481 " interval="+(_saveIntervalSec * 1000L)+
482 " lastNode="+memSession._lastNode+
483 " thisNode="+getSessionIdManager().getWorkerName()+
484 " difference="+(now - memSession._lastSaved));
485 }
486
487 try
488 {
489 if (memSession==null)
490 {
491 LOG.debug("getSession("+idInCluster+"): no session in session map. Reloading session data from db.");
492 session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
493 }
494 else if ((now - memSession._lastSaved) >= (_saveIntervalSec * 1000L))
495 {
496 LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
497 session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
498 }
499 else
500 {
501 LOG.debug("getSession("+idInCluster+"): session in session map");
502 session = memSession;
503 }
504 }
505 catch (Exception e)
506 {
507 LOG.warn("Unable to load session "+idInCluster, e);
508 return null;
509 }
510
511
512
513 if (session != null)
514 {
515
516 if (!session.getLastNode().equals(getSessionIdManager().getWorkerName()) || memSession==null)
517 {
518
519 if (session._expiryTime <= 0 || session._expiryTime > now)
520 {
521 if (LOG.isDebugEnabled())
522 LOG.debug("getSession("+idInCluster+"): lastNode="+session.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName());
523
524 session.setLastNode(getSessionIdManager().getWorkerName());
525 _sessions.put(idInCluster, session);
526
527
528 try
529 {
530 updateSessionNode(session);
531 session.didActivate();
532 }
533 catch (Exception e)
534 {
535 LOG.warn("Unable to update freshly loaded session "+idInCluster, e);
536 return null;
537 }
538 }
539 else
540 {
541 LOG.debug("getSession ({}): Session has expired", idInCluster);
542
543
544 _jdbcSessionIdMgr.removeSession(idInCluster);
545 session=null;
546 }
547
548 }
549 else
550 LOG.debug("getSession({}): Session not stale {}", idInCluster,session);
551 }
552 else
553 {
554
555 LOG.debug("getSession({}): No session in database matching id={}",idInCluster,idInCluster);
556 }
557
558 return session;
559 }
560 }
561
562
563
564
565
566
567
568 @Override
569 public int getSessions()
570 {
571 int size = 0;
572 synchronized (this)
573 {
574 size = _sessions.size();
575 }
576 return size;
577 }
578
579
580
581
582
583
584
585 @Override
586 public void doStart() throws Exception
587 {
588 if (_sessionIdManager==null)
589 throw new IllegalStateException("No session id manager defined");
590
591 _jdbcSessionIdMgr = (JDBCSessionIdManager)_sessionIdManager;
592
593 _sessions = new ConcurrentHashMap<String, AbstractSession>();
594
595 super.doStart();
596 }
597
598
599
600
601
602
603
604 @Override
605 public void doStop() throws Exception
606 {
607 _sessions.clear();
608 _sessions = null;
609
610 super.doStop();
611 }
612
613 @Override
614 protected void invalidateSessions()
615 {
616
617
618
619
620
621
622 }
623
624
625
626
627
628
629 public void renewSessionId (String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
630 {
631 Session session = null;
632 synchronized (this)
633 {
634 try
635 {
636 session = (Session)_sessions.remove(oldClusterId);
637 if (session != null)
638 {
639 session.setClusterId(newClusterId);
640 session.setNodeId(newNodeId);
641 _sessions.put(newClusterId, session);
642 session.save();
643 }
644 }
645 catch (Exception e)
646 {
647 LOG.warn(e);
648 }
649 }
650 }
651
652
653
654
655
656
657
658
659 protected void invalidateSession (String idInCluster)
660 {
661 Session session = null;
662 synchronized (this)
663 {
664 session = (Session)_sessions.get(idInCluster);
665 }
666
667 if (session != null)
668 {
669 session.invalidate();
670 }
671 }
672
673
674
675
676
677
678
679 @Override
680 protected boolean removeSession(String idInCluster)
681 {
682 synchronized (this)
683 {
684 Session session = (Session)_sessions.remove(idInCluster);
685 try
686 {
687 if (session != null)
688 deleteSession(session);
689 }
690 catch (Exception e)
691 {
692 LOG.warn("Problem deleting session id="+idInCluster, e);
693 }
694 return session!=null;
695 }
696 }
697
698
699
700
701
702
703
704 @Override
705 protected void addSession(AbstractSession session)
706 {
707 if (session==null)
708 return;
709
710 synchronized (this)
711 {
712 _sessions.put(session.getClusterId(), session);
713 }
714
715
716
717 try
718 {
719 synchronized (session)
720 {
721 session.willPassivate();
722 storeSession(((JDBCSessionManager.Session)session));
723 session.didActivate();
724 }
725 }
726 catch (Exception e)
727 {
728 LOG.warn("Unable to store new session id="+session.getId() , e);
729 }
730 }
731
732
733
734
735
736
737
738 @Override
739 protected AbstractSession newSession(HttpServletRequest request)
740 {
741 return new Session(request);
742 }
743
744
745
746
747
748
749
750 @Override
751 public void removeSession(AbstractSession session, boolean invalidate)
752 {
753
754 boolean removed = false;
755
756 synchronized (this)
757 {
758
759 if (_sessions.containsKey(session.getClusterId()))
760 {
761 removed = true;
762 removeSession(session.getClusterId());
763 }
764 }
765
766 if (removed)
767 {
768
769 _sessionIdManager.removeSession(session);
770
771 if (invalidate)
772 _sessionIdManager.invalidateAll(session.getClusterId());
773
774 if (invalidate && !_sessionListeners.isEmpty())
775 {
776 HttpSessionEvent event=new HttpSessionEvent(session);
777 for (HttpSessionListener l : _sessionListeners)
778 l.sessionDestroyed(event);
779 }
780 if (!invalidate)
781 {
782 session.willPassivate();
783 }
784 }
785 }
786
787
788
789
790
791
792
793
794 protected Set<String> expire (Set<String> sessionIds)
795 {
796
797 if (isStopping() || isStopped())
798 return null;
799
800
801 Thread thread=Thread.currentThread();
802 ClassLoader old_loader=thread.getContextClassLoader();
803
804 Set<String> successfullyExpiredIds = new HashSet<String>();
805 try
806 {
807 Iterator<?> itor = sessionIds.iterator();
808 while (itor.hasNext())
809 {
810 String sessionId = (String)itor.next();
811 if (LOG.isDebugEnabled())
812 LOG.debug("Expiring session id "+sessionId);
813
814 Session session = (Session)_sessions.get(sessionId);
815
816
817 if (session == null)
818 {
819 if (LOG.isDebugEnabled())LOG.debug("Force loading session id "+sessionId);
820 session = loadSession(sessionId, canonicalize(_context.getContextPath()), getVirtualHost(_context));
821 if (session != null)
822 {
823
824
825 synchronized (this)
826 {
827 _sessions.put(session.getClusterId(), session);
828 }
829 }
830 else
831 {
832 if (LOG.isDebugEnabled())
833 LOG.debug("Unrecognized session id="+sessionId);
834 continue;
835 }
836 }
837
838 if (session != null)
839 {
840 session.timeout();
841 successfullyExpiredIds.add(session.getClusterId());
842 }
843 }
844 return successfullyExpiredIds;
845 }
846 catch (Throwable t)
847 {
848 LOG.warn("Problem expiring sessions", t);
849 return successfullyExpiredIds;
850 }
851 finally
852 {
853 thread.setContextClassLoader(old_loader);
854 }
855 }
856
857
858
859
860
861
862
863
864 protected Session loadSession (final String id, final String canonicalContextPath, final String vhost)
865 throws Exception
866 {
867 final AtomicReference<Session> _reference = new AtomicReference<Session>();
868 final AtomicReference<Exception> _exception = new AtomicReference<Exception>();
869 Runnable load = new Runnable()
870 {
871
872
873
874 @SuppressWarnings("unchecked")
875 public void run()
876 {
877 try (Connection connection = getConnection();
878 PreparedStatement statement = _jdbcSessionIdMgr._dbAdaptor.getLoadStatement(connection, id, canonicalContextPath, vhost);
879 ResultSet result = statement.executeQuery())
880 {
881 Session session = null;
882 if (result.next())
883 {
884 long maxInterval = result.getLong("maxInterval");
885 if (maxInterval == JDBCSessionIdManager.MAX_INTERVAL_NOT_SET)
886 {
887 maxInterval = getMaxInactiveInterval();
888 }
889 session = new Session(id, result.getString(_jdbcSessionIdMgr._sessionTableRowId),
890 result.getLong("createTime"),
891 result.getLong("accessTime"),
892 maxInterval);
893 session.setCookieSet(result.getLong("cookieTime"));
894 session.setLastAccessedTime(result.getLong("lastAccessTime"));
895 session.setLastNode(result.getString("lastNode"));
896 session.setLastSaved(result.getLong("lastSavedTime"));
897 session.setExpiryTime(result.getLong("expiryTime"));
898 session.setCanonicalContext(result.getString("contextPath"));
899 session.setVirtualHost(result.getString("virtualHost"));
900
901 try (InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map");
902 ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
903 {
904 Object o = ois.readObject();
905 session.addAttributes((Map<String,Object>)o);
906 }
907
908 if (LOG.isDebugEnabled())
909 LOG.debug("LOADED session "+session);
910 }
911 else
912 if (LOG.isDebugEnabled())
913 LOG.debug("Failed to load session "+id);
914 _reference.set(session);
915 }
916 catch (Exception e)
917 {
918 _exception.set(e);
919 }
920 }
921 };
922
923 if (_context==null)
924 load.run();
925 else
926 _context.getContextHandler().handle(load);
927
928 if (_exception.get()!=null)
929 {
930
931
932 _jdbcSessionIdMgr.removeSession(id);
933 throw _exception.get();
934 }
935
936 return _reference.get();
937 }
938
939
940
941
942
943
944
945 protected void storeSession (Session session)
946 throws Exception
947 {
948 if (session==null)
949 return;
950
951
952 try (Connection connection = getConnection();
953 PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._insertSession))
954 {
955 String rowId = calculateRowId(session);
956
957 long now = System.currentTimeMillis();
958 connection.setAutoCommit(true);
959 statement.setString(1, rowId);
960 statement.setString(2, session.getId());
961 statement.setString(3, session.getCanonicalContext());
962 statement.setString(4, session.getVirtualHost());
963 statement.setString(5, getSessionIdManager().getWorkerName());
964 statement.setLong(6, session.getAccessed());
965 statement.setLong(7, session.getLastAccessedTime());
966 statement.setLong(8, session.getCreationTime());
967 statement.setLong(9, session.getCookieSet());
968 statement.setLong(10, now);
969 statement.setLong(11, session.getExpiryTime());
970 statement.setLong(12, session.getMaxInactiveInterval());
971
972 ByteArrayOutputStream baos = new ByteArrayOutputStream();
973 ObjectOutputStream oos = new ObjectOutputStream(baos);
974 oos.writeObject(session.getAttributeMap());
975 oos.flush();
976 byte[] bytes = baos.toByteArray();
977
978 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
979 statement.setBinaryStream(13, bais, bytes.length);
980
981
982 statement.executeUpdate();
983 session.setRowId(rowId);
984 session.setLastSaved(now);
985 }
986 if (LOG.isDebugEnabled())
987 LOG.debug("Stored session "+session);
988 }
989
990
991
992
993
994
995
996
997 protected void updateSession (Session data)
998 throws Exception
999 {
1000 if (data==null)
1001 return;
1002
1003 try (Connection connection = getConnection();
1004 PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSession))
1005 {
1006 long now = System.currentTimeMillis();
1007 connection.setAutoCommit(true);
1008 statement.setString(1, data.getId());
1009 statement.setString(2, getSessionIdManager().getWorkerName());
1010 statement.setLong(3, data.getAccessed());
1011 statement.setLong(4, data.getLastAccessedTime());
1012 statement.setLong(5, now);
1013 statement.setLong(6, data.getExpiryTime());
1014 statement.setLong(7, data.getMaxInactiveInterval());
1015
1016 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1017 ObjectOutputStream oos = new ObjectOutputStream(baos);
1018 oos.writeObject(data.getAttributeMap());
1019 oos.flush();
1020 byte[] bytes = baos.toByteArray();
1021 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1022
1023 statement.setBinaryStream(8, bais, bytes.length);
1024 statement.setString(9, data.getRowId());
1025 statement.executeUpdate();
1026
1027 data.setLastSaved(now);
1028 }
1029 if (LOG.isDebugEnabled())
1030 LOG.debug("Updated session "+data);
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040 protected void updateSessionNode (Session data)
1041 throws Exception
1042 {
1043 String nodeId = getSessionIdManager().getWorkerName();
1044 try (Connection connection = getConnection();
1045 PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionNode))
1046 {
1047 connection.setAutoCommit(true);
1048 statement.setString(1, nodeId);
1049 statement.setString(2, data.getRowId());
1050 statement.executeUpdate();
1051 }
1052 if (LOG.isDebugEnabled())
1053 LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId);
1054 }
1055
1056
1057
1058
1059
1060
1061
1062 private void updateSessionAccessTime (Session data)
1063 throws Exception
1064 {
1065 try (Connection connection = getConnection();
1066 PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionAccessTime))
1067 {
1068 long now = System.currentTimeMillis();
1069 connection.setAutoCommit(true);
1070 statement.setString(1, getSessionIdManager().getWorkerName());
1071 statement.setLong(2, data.getAccessed());
1072 statement.setLong(3, data.getLastAccessedTime());
1073 statement.setLong(4, now);
1074 statement.setLong(5, data.getExpiryTime());
1075 statement.setLong(6, data.getMaxInactiveInterval());
1076 statement.setString(7, data.getRowId());
1077
1078 statement.executeUpdate();
1079 data.setLastSaved(now);
1080 }
1081 if (LOG.isDebugEnabled())
1082 LOG.debug("Updated access time session id="+data.getId());
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 protected void deleteSession (Session data)
1096 throws Exception
1097 {
1098 try (Connection connection = getConnection();
1099 PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._deleteSession))
1100 {
1101 connection.setAutoCommit(true);
1102 statement.setString(1, data.getRowId());
1103 statement.executeUpdate();
1104 if (LOG.isDebugEnabled())
1105 LOG.debug("Deleted Session "+data);
1106 }
1107 }
1108
1109
1110
1111
1112
1113
1114
1115
1116 private Connection getConnection ()
1117 throws SQLException
1118 {
1119 return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129 private String calculateRowId (Session data)
1130 {
1131 String rowId = canonicalize(_context.getContextPath());
1132 rowId = rowId + "_" + getVirtualHost(_context);
1133 rowId = rowId+"_"+data.getId();
1134 return rowId;
1135 }
1136
1137
1138
1139
1140
1141
1142
1143
1144 private static String getVirtualHost (ContextHandler.Context context)
1145 {
1146 String vhost = "0.0.0.0";
1147
1148 if (context==null)
1149 return vhost;
1150
1151 String [] vhosts = context.getContextHandler().getVirtualHosts();
1152 if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
1153 return vhost;
1154
1155 return vhosts[0];
1156 }
1157
1158
1159
1160
1161
1162
1163
1164 private static String canonicalize (String path)
1165 {
1166 if (path==null)
1167 return "";
1168
1169 return path.replace('/', '_').replace('.','_').replace('\\','_');
1170 }
1171 }