blob: 65cfefadd010570e58e843366166c98ace7775d0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.help.internal.webapp.servlet;
import java.io.*;
import java.util.HashSet;
import javax.servlet.http.*;
import org.eclipse.help.internal.webapp.*;
import org.eclipse.help.internal.webapp.data.*;
/**
* Utilities for working with cookies
*
* @since 3.0
*/
public class CookieUtil {
private static final int COOKIE_LIFE = 5 * 365 * 24 * 60 * 60;
private static final int MAX_COOKIE_PAYLOAD = 4096
- "wset_contents01=".length() - "81920<".length() - 1; //$NON-NLS-1$ //$NON-NLS-2$
/**
* @return null or String
*/
public static String getCookieValue(String name, HttpServletRequest request) {
String ret = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
ret = cookie.getValue();
break;
}
}
}
if (HelpWebappPlugin.DEBUG_WORKINGSETS) {
System.out.println("CookieUtil.getCookieValue(" //$NON-NLS-1$
+ name + ", " //$NON-NLS-1$
+ request.getRequestURI() + ") returning " //$NON-NLS-1$
+ ret);
}
return ret;
}
public static void setCookieValue(String name, String value,
HttpServletRequest request, HttpServletResponse response) {
Cookie cookie = new Cookie(name, value);
cookie.setMaxAge(COOKIE_LIFE);
if ( needsCookiePath(request)) {
cookie.setPath(getCookiePath(request)); // Only set path if necessary
}
response.addCookie(cookie);
if (HelpWebappPlugin.DEBUG_WORKINGSETS) {
System.out
.println("CookieUtil.setCookieValue(" + name + ", " + value + ",...)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
public static void setCookieValueWithoutPath(String name, String value,
HttpServletRequest request, HttpServletResponse response ) {
Cookie cookie = new Cookie(name, value);
cookie.setMaxAge(COOKIE_LIFE);
response.addCookie(cookie);
if (HelpWebappPlugin.DEBUG_WORKINGSETS) {
System.out
.println("CookieUtil.setCookieValueWithoutPath(" + name + ", " + value + ",...)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
private static boolean needsCookiePath(HttpServletRequest request) {
// All cookies should be at the same path level as the context ( /help )
// The cookie path needs to be set if there are more path segments
// between the context path and file name
String requestURI = request.getRequestURI();
String contextPath = request.getContextPath();
return requestURI.indexOf('/', contextPath.length() + 1) > 0;
}
private static String getCookiePath(HttpServletRequest request) {
return request.getContextPath() + '/';
}
public static void deleteCookie(String name, HttpServletRequest request, HttpServletResponse response) {
deleteCookieUsingPath(name, request, response, getCookiePath(request));
}
protected static void deleteCookieUsingPath(String name, HttpServletRequest request,
HttpServletResponse response, String cookiePath) {
Cookie cookie = new Cookie(name, ""); //$NON-NLS-1$
String requestURI = request.getRequestURI();
if (!(requestURI.startsWith(cookiePath) && requestURI.indexOf('/', cookiePath.length() + 1) == -1)) {
cookie.setPath(cookiePath);
}
cookie.setMaxAge(0);
response.addCookie(cookie);
}
public static void deleteObsoleteCookies(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
HashSet<String> cookiesToKeep= new HashSet<String>();
HashSet<String> cookiesToDelete = new HashSet<String>();
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (isObsoleteCookie(name) || cookiesToKeep.contains(name)) {
cookiesToDelete.add(name);
}
cookiesToKeep.add(name); {
}
}
for (String name : cookiesToDelete) {
deleteCookieUsingPath(name, request, response, request.getContextPath() + "/advanced/"); //$NON-NLS-1$
deleteCookieUsingPath(name, request, response, "/"); //$NON-NLS-1$
}
}
}
/*
* Is this one of the cookies that was used before Eclipse 3.6 of the
* form wset_nn
*/
private static boolean isObsoleteCookie(String name) {
final String WSET_PREFIX = "wset"; //$NON-NLS-1$
if (!name.startsWith(WSET_PREFIX)) {
return false;
}
for (int i = WSET_PREFIX.length(); i < name.length(); i++) {
char suffixChar = name.charAt(i);
if (suffixChar < '0' || suffixChar > '9') {
return false;
}
}
return true;
}
/**
* Saves string in multiple browser cookies. Cookies can store limited
* length string. This method will attemt to split string among multiple
* cookies. The following cookies will be set name1=length <substing1
* name2=substring2 ... namen=substringn
*
* @param data
* a string containing legal characters for cookie value
* @throws IOException
* when data is too long.
*/
public static void saveString(String name, String data, int maxCookies,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
int len = data.length();
int n = len / MAX_COOKIE_PAYLOAD;
if (n > maxCookies) {
throw new IOException(WebappResources.getString(
"CookieUtil.tooManyCookiesNeeded", UrlUtil.getLocaleObj( //$NON-NLS-1$
request, response)));
}
for (int i = 1; i <= n; i++) {
if (i == 1) {
setCookieValue(name + "1", //$NON-NLS-1$
len + "<" + data.substring(0, MAX_COOKIE_PAYLOAD), //$NON-NLS-1$
request, response);
} else {
setCookieValue(name + i, data.substring(MAX_COOKIE_PAYLOAD
* (i - 1), MAX_COOKIE_PAYLOAD * i), request, response);
}
}
if (len % MAX_COOKIE_PAYLOAD > 0) {
if (n == 0) {
setCookieValue(name + "1", //$NON-NLS-1$
len + "<" + data.substring(0, len), //$NON-NLS-1$
request, response);
} else {
setCookieValue(name + (n + 1), data.substring(
MAX_COOKIE_PAYLOAD * n, len), request, response);
}
}
// if using less cookies than maximum, delete not needed cookies from
// last time
for (int i = n + 1; i <= maxCookies; i++) {
if (i == n + 1 && len % MAX_COOKIE_PAYLOAD > 0) {
continue;
}
if (getCookieValue(name + i, request) != null) {
deleteCookie(name + i, request, response);
} else {
break;
}
}
}
/**
* @return null or String
*/
public static String restoreString(String name, HttpServletRequest request) {
String value1 = CookieUtil.getCookieValue(name + "1", request); //$NON-NLS-1$
if (value1 == null) {
// no cookie
return null;
}
String lengthAndSubstring1[] = value1.split("<"); //$NON-NLS-1$
if (lengthAndSubstring1.length < 2) {
return null;
}
int len = 0;
try {
len = Integer.parseInt(lengthAndSubstring1[0]);
} catch (NumberFormatException nfe) {
return null;
}
if (len <= 0) {
return null;
}
StringBuffer data = new StringBuffer(len);
data.append(lengthAndSubstring1[1]);
int n = len / MAX_COOKIE_PAYLOAD;
for (int i = 2; i <= n; i++) {
String substring = CookieUtil.getCookieValue(name + i, request);
if (substring == null) {
return null;
}
data.append(substring);
}
if (len % MAX_COOKIE_PAYLOAD > 0 && n > 0) {
String substring = CookieUtil.getCookieValue(name + (n + 1),
request);
if (substring == null) {
return null;
}
data.append(substring);
}
if (data.length() != len) {
return null;
}
return data.toString();
}
}