| 68 | 1 /* | 
|  | 2 Copyright (c) 2008  Franklin Schmidt <fschmidt@gmail.com> | 
|  | 3 | 
|  | 4 Permission is hereby granted, free of charge, to any person obtaining a copy | 
|  | 5 of this software and associated documentation files (the "Software"), to deal | 
|  | 6 in the Software without restriction, including without limitation the rights | 
|  | 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
|  | 8 copies of the Software, and to permit persons to whom the Software is | 
|  | 9 furnished to do so, subject to the following conditions: | 
|  | 10 | 
|  | 11 The above copyright notice and this permission notice shall be included in | 
|  | 12 all copies or substantial portions of the Software. | 
|  | 13 | 
|  | 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|  | 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|  | 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 
|  | 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|  | 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
|  | 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
|  | 20 THE SOFTWARE. | 
|  | 21 */ | 
|  | 22 | 
|  | 23 package fschmidt.util.servlet; | 
|  | 24 | 
|  | 25 import fschmidt.util.java.Base64; | 
|  | 26 import fschmidt.util.java.HtmlUtils; | 
|  | 27 | 
|  | 28 import javax.servlet.http.Cookie; | 
|  | 29 import javax.servlet.http.HttpServletRequest; | 
|  | 30 import javax.servlet.http.HttpServletResponse; | 
|  | 31 import javax.servlet.http.HttpUtils; | 
|  | 32 import java.io.IOException; | 
|  | 33 import java.net.MalformedURLException; | 
|  | 34 import java.net.URL; | 
|  | 35 import java.util.Collections; | 
|  | 36 import java.util.Enumeration; | 
|  | 37 import java.util.Iterator; | 
|  | 38 import java.util.Map; | 
|  | 39 | 
|  | 40 | 
|  | 41 public final class ServletUtils { | 
|  | 42 | 
|  | 43 	private ServletUtils() { throw new RuntimeException(); } | 
|  | 44 | 
|  | 45 	public static String getQueryString(HttpServletRequest request) { | 
|  | 46 		return getQueryString(request,0); | 
|  | 47 	} | 
|  | 48 | 
|  | 49 	public static String getQueryString(HttpServletRequest request,int maxValueLen) { | 
|  | 50 		String method = request.getMethod(); | 
|  | 51 		if( method.equals("GET") ) | 
|  | 52 			return request.getQueryString(); | 
|  | 53 		if( !method.equals("POST") && !method.equals("HEAD") ) | 
|  | 54 			throw new RuntimeException(method); | 
|  | 55 		Enumeration en = request.getParameterNames(); | 
|  | 56 		StringBuilder queryBuf = new StringBuilder(); | 
|  | 57 		if( !en.hasMoreElements() ) | 
|  | 58 			return null; | 
|  | 59 		do { | 
|  | 60 			String param = (String)en.nextElement(); | 
|  | 61 			String value = request.getParameter(param); | 
|  | 62 			if( maxValueLen > 0 ) { | 
|  | 63 				int len = value.length(); | 
|  | 64 				if( len > maxValueLen ) | 
|  | 65 					value = value.substring(0,maxValueLen) + "..." + (len-maxValueLen); | 
|  | 66 			} | 
|  | 67 			queryBuf.append(param); | 
|  | 68 			queryBuf.append('='); | 
|  | 69 			queryBuf.append(value); | 
|  | 70 			queryBuf.append('&'); | 
|  | 71 		} while( en.hasMoreElements() ); | 
|  | 72 		queryBuf.deleteCharAt(queryBuf.length() - 1); | 
|  | 73 		return queryBuf.toString(); | 
|  | 74 	} | 
|  | 75 | 
|  | 76 	public static String getCurrentURL(HttpServletRequest request) { | 
|  | 77 		return getCurrentURL(request,0); | 
|  | 78 	} | 
|  | 79 | 
|  | 80 	public static String getCurrentURL(HttpServletRequest request,int maxValueLen) { | 
|  | 81 //		StringBuffer buf = HttpUtils.getRequestURL(request); | 
|  | 82 		StringBuffer buf = request.getRequestURL(); | 
|  | 83 		String qStr = getQueryString(request,maxValueLen); | 
|  | 84 		if(qStr != null && qStr.length() > 0) { | 
|  | 85 			buf.append('?'); | 
|  | 86 			buf.append(qStr); | 
|  | 87 		} | 
|  | 88 		return buf.toString(); | 
|  | 89 	} | 
|  | 90 | 
|  | 91 	public static String fullURL(HttpServletRequest request,String relativeURL) | 
|  | 92 		throws MalformedURLException | 
|  | 93 	{ | 
|  | 94 		return new URL(new URL(request.getRequestURL().toString()),relativeURL).toString(); | 
|  | 95 	} | 
|  | 96 | 
|  | 97 	public static String getHost(HttpServletRequest request) { | 
|  | 98 /* | 
|  | 99 		String host = request.getHeader("host"); | 
|  | 100 		if( host.endsWith(":80") ) | 
|  | 101 			host = host.substring(0,host.length()-3); | 
|  | 102 		return host; | 
|  | 103 */ | 
|  | 104 		String host = request.getServerName(); | 
|  | 105 		int port = request.getServerPort(); | 
|  | 106 		if( port != 80 ) { | 
|  | 107 			host += ":" + port; | 
|  | 108 		} | 
|  | 109 		return host; | 
|  | 110 	} | 
|  | 111 | 
|  | 112 	static String getContextUrl(String scheme,String host,String contextPath) { | 
|  | 113 		StringBuilder buf = new StringBuilder(); | 
|  | 114 		buf.append( scheme ); | 
|  | 115 		buf.append( "://" ); | 
|  | 116 		buf.append( host ); | 
|  | 117 		buf.append( contextPath ); | 
|  | 118 		return buf.toString(); | 
|  | 119 	} | 
|  | 120 | 
|  | 121 	public static String getContextURL(HttpServletRequest request) { | 
|  | 122 		return getContextUrl( request.getScheme(), getHost(request), request.getContextPath() ); | 
|  | 123 	} | 
|  | 124 | 
|  | 125 	public static String getServletPath(HttpServletRequest request,String relativeURL) | 
|  | 126 		throws MalformedURLException | 
|  | 127 	{ | 
|  | 128 		int i = relativeURL.indexOf('?'); | 
|  | 129 		if( i != -1 ) | 
|  | 130 			relativeURL = relativeURL.substring(0,i); | 
|  | 131 		String url = fullURL(request,relativeURL); | 
|  | 132 		String context = getContextURL(request); | 
|  | 133 		if( !url.startsWith(context) ) | 
|  | 134 			throw new RuntimeException("context="+context+" url="+url); | 
|  | 135 		return url.substring(context.length()); | 
|  | 136 	} | 
|  | 137 | 
|  | 138 	public static Map<String,String[]> getParameterMap(String url) { | 
|  | 139 		int i = url.indexOf('?'); | 
|  | 140 		if( i == -1 ) | 
|  | 141 			return Collections.emptyMap(); | 
|  | 142 		String query = url.substring(i+1); | 
|  | 143 		return parseQueryString(query); | 
|  | 144 	} | 
|  | 145 | 
|  | 146 	@SuppressWarnings("unchecked") | 
|  | 147 	private static Map<String,String[]> parseQueryString(String query) { | 
|  | 148 		return HttpUtils.parseQueryString(query); | 
|  | 149 	} | 
|  | 150 | 
|  | 151 	public static String getQueryString(Map<String,String[]> params) { | 
|  | 152 		StringBuilder buf = new StringBuilder(); | 
|  | 153 		for( Iterator<Map.Entry<String,String[]>> iter=params.entrySet().iterator(); iter.hasNext(); ) { | 
|  | 154 			Map.Entry<String,String[]> entry = iter.next(); | 
|  | 155 			String name = entry.getKey(); | 
|  | 156 			String[] values = entry.getValue(); | 
|  | 157 			for( int i=0; i<values.length; i++ ) { | 
|  | 158 				if( buf.length() > 0 ) | 
|  | 159 					buf.append( '&' ); | 
|  | 160 				buf.append( name ); | 
|  | 161 				buf.append( '=' ); | 
|  | 162 				buf.append( HtmlUtils.urlEncode(values[i]) ); | 
|  | 163 			} | 
|  | 164 		} | 
|  | 165 		return buf.toString(); | 
|  | 166 	} | 
|  | 167 | 
|  | 168 	private static String escape(String value) { | 
|  | 169 		return value.replaceAll(";", "%3B"); | 
|  | 170 	} | 
|  | 171 | 
|  | 172 	private static String unescape(String value) { | 
|  | 173 		return value.replaceAll("%3B", ";"); | 
|  | 174 	} | 
|  | 175 | 
|  | 176 	private static Cookie getCookie(HttpServletRequest request,String name) { | 
|  | 177 		Cookie[] cookies = request.getCookies(); | 
|  | 178 		if( cookies == null ) | 
|  | 179 			return null; | 
|  | 180 		for (Cookie cookie : cookies) { | 
|  | 181 			if (cookie.getName().equals(name)) | 
|  | 182 				return cookie; | 
|  | 183 		} | 
|  | 184 		return null; | 
|  | 185 	} | 
|  | 186 | 
|  | 187 	public static String getCookieValue(HttpServletRequest request,String name) { | 
|  | 188 		Cookie cookie = getCookie(request,name); | 
|  | 189 		return cookie==null ? null : unescape(cookie.getValue()); | 
|  | 190 	} | 
|  | 191 | 
|  | 192 	public static void setCookie(HttpServletRequest request,HttpServletResponse response,String name,String value,boolean isPersistent, String domain) { | 
|  | 193 		Cookie cookie = getCookie(request,name); | 
|  | 194 		if( cookie==null || !cookie.getValue().equals(value) ) { | 
|  | 195 			cookie = new Cookie(name, escape(value)); | 
|  | 196 			cookie.setPath("/"); | 
|  | 197 			if (domain != null && domain.length() > 0) | 
|  | 198 				cookie.setDomain(domain); | 
|  | 199 			if( isPersistent ) | 
|  | 200 				cookie.setMaxAge(10000000); | 
|  | 201 			response.addCookie(cookie); | 
|  | 202 		} | 
|  | 203 	} | 
|  | 204 | 
|  | 205 	public static void removeCookie(HttpServletRequest request, | 
|  | 206 									HttpServletResponse response, | 
|  | 207 									String name, | 
|  | 208 									String domain | 
|  | 209 | 
|  | 210 	) { | 
|  | 211 		Cookie cookie = getCookie(request, name); | 
|  | 212 		if(cookie != null) { | 
|  | 213 			Cookie delCookie = new Cookie(name, "delete"); | 
|  | 214 			delCookie.setPath("/"); | 
|  | 215 			delCookie.setMaxAge(0); | 
|  | 216 			if (domain != null && domain.length() > 0) | 
|  | 217 				delCookie.setDomain(domain); | 
|  | 218 			response.addCookie(delCookie); | 
|  | 219 		} | 
|  | 220 	} | 
|  | 221 | 
|  | 222 | 
|  | 223 	public static String getRemoteAddr(HttpServletRequest request) { | 
|  | 224 		String addr = request.getHeader("X-Forwarded-For"); | 
|  | 225 		if( addr==null ) | 
|  | 226 			addr = request.getRemoteAddr(); | 
|  | 227 		return addr; | 
|  | 228 	} | 
|  | 229 | 
|  | 230 /* | 
|  | 231 	public static boolean authenticate(HttpServletRequest request,HttpServletResponse response,String authRealm,String authUsernameAndPassword) | 
|  | 232 		throws IOException | 
|  | 233 	{ | 
|  | 234 		String auth = request.getHeader("Authorization"); | 
|  | 235 		if( auth==null ) { | 
|  | 236 			response.setHeader("WWW-Authenticate","Basic realm=\""+authRealm+"\""); | 
|  | 237 			response.sendError(HttpServletResponse.SC_UNAUTHORIZED); | 
|  | 238 			return false; | 
|  | 239 		} | 
|  | 240 		String[] a = auth.split(" +"); | 
|  | 241 		if( a.length != 2 ) | 
|  | 242 			throw new RuntimeException("auth = "+auth); | 
|  | 243 		if( !a[0].equals("Basic") ) | 
|  | 244 			throw new RuntimeException("auth = "+auth); | 
|  | 245 		if( !new String(Base64.decode(a[1])).equals(authUsernameAndPassword) ) { | 
|  | 246 			response.setHeader("WWW-Authenticate","Basic realm=\""+authRealm+"\""); | 
|  | 247 			response.sendError(HttpServletResponse.SC_UNAUTHORIZED); | 
|  | 248 			return false; | 
|  | 249 		} | 
|  | 250 		return true; | 
|  | 251 	} | 
|  | 252 */ | 
|  | 253 	public static String getAuthorization(HttpServletRequest request) { | 
|  | 254 		String auth = request.getHeader("Authorization"); | 
|  | 255 		if( auth==null ) | 
|  | 256 			return null; | 
|  | 257 		String[] a = auth.split(" +"); | 
|  | 258 		if( a.length != 2 ) | 
|  | 259 			throw new RuntimeException("auth = "+auth); | 
|  | 260 		if( !a[0].equals("Basic") ) | 
|  | 261 			throw new RuntimeException("auth = "+auth); | 
|  | 262 		return new String(Base64.decode(a[1])); | 
|  | 263 	} | 
|  | 264 | 
|  | 265 	public static void sendAuthenticate(HttpServletResponse response,String authRealm) | 
|  | 266 		throws IOException | 
|  | 267 	{ | 
|  | 268 		response.setHeader("WWW-Authenticate","Basic realm=\""+authRealm+"\""); | 
|  | 269 		response.sendError(HttpServletResponse.SC_UNAUTHORIZED); | 
|  | 270 	} | 
|  | 271 } |