Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 2e1ef9e9bb240866a835565223d3edc8a96207f9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*******************************************************************************
 * Copyright (c) 2018 Liferay, Inc.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Liferay, Inc. - Bug 530063 - CNFE when session replication
 *                    is used with equinox.http.servlet in bridge mode
 ******************************************************************************/

package org.eclipse.equinox.http.servlet.internal.servlet;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.http.HttpSession;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
import org.eclipse.equinox.http.servlet.session.HttpSessionInvalidator;

/**
 * @since 1.5
 */
public class HttpSessionTracker implements HttpSessionInvalidator {

	public HttpSessionTracker(HttpServiceRuntimeImpl httpServiceRuntime) {
		this.httpServiceRuntime = httpServiceRuntime;
	}

	@Override
	public void invalidate(String sessionId, boolean invalidateParent) {
		Set<HttpSessionAdaptor> httpSessionAdaptors =
			httpSessionAdaptorsMap.remove(sessionId);

		if (httpSessionAdaptors == null) {
			return;
		}

		HttpSession parentSession = null;

		for (HttpSessionAdaptor httpSessionAdaptor : httpSessionAdaptors) {
			parentSession = httpSessionAdaptor.getSession();

			httpSessionAdaptor.invalidate();
		}

		if (invalidateParent && parentSession != null) {
			try {
				parentSession.invalidate();
			}
			catch (IllegalStateException ise) {
				httpServiceRuntime.log(
					"Session was already invalidated!", ise); //$NON-NLS-1$
			}
		}
	}

	public void addHttpSessionAdaptor(
		String sessionId, HttpSessionAdaptor httpSessionAdaptor) {

		Set<HttpSessionAdaptor> httpSessionAdaptors =
			httpSessionAdaptorsMap.get(sessionId);

		if (httpSessionAdaptors == null) {
			httpSessionAdaptors = Collections.newSetFromMap(
				new ConcurrentHashMap<HttpSessionAdaptor, Boolean>());

			Set<HttpSessionAdaptor> previousHttpSessionAdaptors =
				httpSessionAdaptorsMap.putIfAbsent(
					sessionId, httpSessionAdaptors);

			if (previousHttpSessionAdaptors != null) {
				httpSessionAdaptors = previousHttpSessionAdaptors;
			}
		}

		httpSessionAdaptors.add(httpSessionAdaptor);
	}

	public void clear() {
		// At this point there should be no left over sessions. If
		// there are we'll log it because there's some kind of leak.
		if (!httpSessionAdaptorsMap.isEmpty()) {
			httpServiceRuntime.log(
				"There are HttpSessionAdaptors left over. There might be a context or session leak!"); //$NON-NLS-1$
		}
	}

	public boolean removeHttpSessionAdaptor(
		String sessionId, HttpSessionAdaptor httpSessionAdaptor) {

		Set<HttpSessionAdaptor> httpSessionAdaptors =
			httpSessionAdaptorsMap.get(sessionId);

		if (httpSessionAdaptors == null) {
			return false;
		}

		try {
			return httpSessionAdaptors.remove(httpSessionAdaptor);
		}
		finally {
			if (httpSessionAdaptors.isEmpty()) {
				httpSessionAdaptorsMap.remove(sessionId, httpSessionAdaptors);
			}
		}
	}

	private final ConcurrentMap<String, Set<HttpSessionAdaptor>>
		httpSessionAdaptorsMap =
			new ConcurrentHashMap<String, Set<HttpSessionAdaptor>>();
	private final HttpServiceRuntimeImpl httpServiceRuntime;

}

Back to the top