| 
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 }
 |