1 4 5 9 10 package org.openlaszlo.utils; 11 12 import java.io.File; 13 import java.io.UnsupportedEncodingException; 14 import java.net.URL; 15 import javax.servlet.ServletContext; 16 import javax.servlet.http.HttpUtils; 17 import javax.servlet.http.HttpServletRequest; 18 import javax.servlet.http.HttpServletResponse; 19 import org.apache.commons.httpclient.methods.*; 20 import org.apache.commons.httpclient.HttpMethodBase; 21 import org.apache.commons.httpclient.Header; 22 import org.apache.commons.httpclient.URI; 23 import org.apache.commons.httpclient.URIException; 24 25 import java.text.SimpleDateFormat; 26 import java.util.TimeZone; 27 import java.util.Date; 28 import java.util.Enumeration; 29 import java.security.*; 30 31 import org.apache.log4j.*; 32 33 import org.openlaszlo.utils.ChainedException; 34 35 38 public class LZHttpUtils { 39 40 private static Logger mLogger = Logger.getLogger(LZHttpUtils.class); 41 42 public static final String CONTENT_ENCODING = "Content-Encoding"; 43 public static final String CONTENT_LENGTH = "Content-Length"; 44 public static final String CONTENT_TYPE = "Content-Type"; 45 public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; 46 public static final String LAST_MODIFIED = "Last-Modified"; 47 public static final String IF_NONE_MATCH = "If-None-Match"; 48 public static final String TRANSFER_ENCODING = "Transfer-Encoding"; 49 public static final String HOST = "Host"; 50 public static final String CONNECTION = "Connection"; 51 public static final String AUTHORIZATION = "Authorization"; 52 public static final String COOKIE = "Cookie"; 53 public static final String CACHE_CONTROL = "Cache-Control"; 54 public static final String USER_AGENT = "User-Agent"; 55 public static final String ACCEPT_ENCODING = "Accept-Encoding"; 56 public static final String RANGE = "Range"; 57 public static final String ACCEPT_RANGES = "Accept-Ranges"; 58 public static final String IF_RANGE = "If-Range"; 59 60 public static final String NO_STORE = "no-store"; 61 public static final String NO_CACHE = "no-cache"; 62 63 64 68 public static URL getRequestURL(HttpServletRequest req) { 69 StringBuffer surl = HttpUtils.getRequestURL(req); 70 String sturl = surl.toString(); if (sturl.indexOf("https") == 0) { 72 try { 73 System.setProperty("java.protocol.handler.pkgs", 74 "com.sun.net.ssl.internal.www.protocol"); 75 Class provClass = Class.forName("com.sun.net.ssl.internal.ssl.Provider"); 76 Provider provider = (Provider)provClass.newInstance(); 77 Security.addProvider(provider); 78 } catch (InstantiationException e) { 79 throw new ChainedException(e); 80 } catch (IllegalAccessException e) { 81 throw new ChainedException(e); 82 } catch (ClassNotFoundException e) { 83 throw new ChainedException(e); 84 } 85 } 86 try { 89 return new URL(surl.toString()); 90 } catch (Exception e) { 91 throw new ChainedException(e); 92 } 93 } 94 95 98 99 102 private static SimpleDateFormat getGMTFormatter() { 103 SimpleDateFormat dateFormatter = 104 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", 105 java.util.Locale.US); 106 TimeZone tz = TimeZone.getTimeZone("GMT"); 107 dateFormatter.setTimeZone(tz); 108 return dateFormatter; 109 } 110 111 114 public static String getDateString(long d) { 115 SimpleDateFormat dateFormatter = getGMTFormatter(); 116 return dateFormatter.format(new Date(d)); 117 } 118 119 123 public static long getDate(String s) { 124 if (s == null || "".equals(s)) { 125 return -1; 126 } 127 try { 128 SimpleDateFormat dateFormatter = getGMTFormatter(); 129 return dateFormatter.parse(s).getTime(); 130 } catch (java.text.ParseException e) { 131 mLogger.warn("bad date string", e); 132 return -1; 133 } 134 } 135 136 146 static public boolean allowForward(String header, Enumeration connEnum) 147 { 148 if (header.toLowerCase().startsWith("content-")) 149 return false; 150 151 if (header.equalsIgnoreCase(CONNECTION)) 152 return false; 153 154 if (header.equalsIgnoreCase(HOST)) 155 return false; 156 157 if (header.equalsIgnoreCase(TRANSFER_ENCODING)) 158 return false; 159 160 if (header.equalsIgnoreCase(IF_MODIFIED_SINCE)) 161 return false; 162 163 if (header.equalsIgnoreCase(LAST_MODIFIED)) 164 return false; 165 166 if (header.equalsIgnoreCase(IF_NONE_MATCH)) 167 return false; 168 169 if (header.equalsIgnoreCase(ACCEPT_ENCODING)) 170 return false; 171 172 if (header.equalsIgnoreCase(RANGE)) 174 return false; 175 176 if (header.equalsIgnoreCase(ACCEPT_RANGES)) 178 return false; 179 180 if (header.equalsIgnoreCase(IF_RANGE)) 182 return false; 183 184 if (connEnum != null) { 187 while (connEnum.hasMoreElements()) { 188 String token = (String)connEnum.nextElement(); 189 if (header.equalsIgnoreCase(token)) 190 return false; 191 } 192 } 193 194 return true; 195 } 196 197 202 static public void proxyRequestHeaders(HttpServletRequest req, 203 HttpMethodBase method) 204 { 205 mLogger.debug("proxyRequestHeaders"); 206 207 Enumeration enum = req.getHeaderNames(); 210 if (enum!=null) { 211 212 Enumeration connEnum = req.getHeaders(CONNECTION); 214 215 while (enum.hasMoreElements()) { 216 String key = (String)enum.nextElement(); 217 if (allowForward(key, connEnum)) { 218 String val = (String)req.getHeader(key); 219 method.addRequestHeader(key,val); 220 mLogger.debug(" " + key + "=" + val); 221 } 222 } 223 224 } else { 225 mLogger.warn("Can't get header names to proxy request headers"); 226 227 Enumeration cookieEnum = req.getHeaders(COOKIE); 228 if (cookieEnum != null) { 229 while (cookieEnum.hasMoreElements()) { 230 String val = (String)cookieEnum.nextElement(); 231 method.addRequestHeader(COOKIE, val); 232 mLogger.debug(" Cookie=" + val); 233 } 234 } 235 236 Enumeration authEnum = req.getHeaders(AUTHORIZATION); 237 if (authEnum != null) { 238 while (authEnum.hasMoreElements()) { 239 String val = (String)authEnum.nextElement(); 240 method.addRequestHeader(AUTHORIZATION, val); 241 mLogger.debug(" Authorization=" + val); 242 } 243 } 244 } 245 } 246 247 254 static public void proxyResponseHeaders(GetMethod meth, 255 HttpServletResponse res, 256 boolean isSecure) 257 { 258 mLogger.debug("proxyResponseHeaders"); 259 260 Header[] hedz = meth.getResponseHeaders(); 261 262 for (int i = 0; i < hedz.length; i++) { 263 String name = hedz[i].getName(); 264 String value = hedz[i].getValue(); 265 if (allowForward(name, null)) { 267 if (isSecure) { 270 if (name.equals("Pragma") && value.equals("no-cache")) 271 continue; 272 if (name.equals("Cache-Control") && value.equals("no-cache")) 273 continue; 274 } 275 276 mLogger.debug(" " + name + "=" + value); 277 278 try { 279 if (name.equals("Date") || name.equals("Server")) { 280 res.setHeader(name, value); 281 } else { 282 res.addHeader(name, value); 283 } 284 } catch (Exception e) { 285 mLogger.error("Exception when proxying a response header: " + e.getMessage()); 286 } 287 } 288 } 289 } 290 291 297 static public String getCookie(HttpServletRequest req, String name) 298 { 299 javax.servlet.http.Cookie[] cookies = req.getCookies(); 300 if (cookies != null) { 301 for (int i=0; i < cookies.length; i++) { 302 javax.servlet.http.Cookie cookie = cookies[i]; 303 if (cookie.getName().equals(name)) { 304 return cookie.getValue(); 305 } 306 } 307 } 308 return null; 309 } 310 311 322 static public String getRealPath(ServletContext ctxt, String path) 323 { 324 String realPath = ctxt.getRealPath(path); 325 if ( realPath != null && File.separatorChar == '\\' ) 326 realPath = realPath.replace('/', '\\'); 327 try { 328 return new File(realPath).getCanonicalPath(); 329 } catch (java.io.IOException e) { 330 throw new org.openlaszlo.utils.ChainedException(e); 331 } 332 } 333 334 341 static public String getRealPath(ServletContext ctxt, HttpServletRequest req) 342 { 343 String uriwithoutcontext = req.getRequestURI().substring(req.getContextPath().length()); 344 if (uriwithoutcontext != null && File.separatorChar == '\\' ) { 345 uriwithoutcontext = uriwithoutcontext.replace('/', '\\'); 346 } 347 return getRealPath(ctxt, "/") + uriwithoutcontext; 348 } 349 350 private static String WEBAPP = "/@WEBAPP@/"; 351 352 361 public static String modifyWEBAPP(HttpServletRequest req, String url) 362 { 363 mLogger.debug("modifyWEBAPP"); 364 if (url.startsWith(WEBAPP)) { 365 mLogger.debug(" Old URL: " + url); 366 String protocol = (req.isSecure()?"https":"http"); 367 String host = req.getServerName(); 368 int port = req.getServerPort(); 369 String cp = req.getContextPath(); 370 url = protocol + "://" + host + ":" + port + cp 371 + url.substring(WEBAPP.length()-1); 372 mLogger.debug(" New URL: " + url); 373 } 374 return url; 375 } 376 377 380 static public void noStore(HttpServletResponse res) { 381 if (res.containsHeader(LZHttpUtils.CACHE_CONTROL)) { 382 mLogger.warn("over-riding back-end cache-control header to: no-store"); 383 } 384 res.setHeader(CACHE_CONTROL, NO_STORE); 385 } 386 387 388 391 static public URI newURI(String s) throws URIException { 392 try { 393 return new URI(s.toCharArray()); 394 } catch (URIException urie) { 395 try { 397 return new URI(s); 398 } catch (Exception e) { 399 throw urie; 401 } 402 } 403 } 404 405 408 public static String urldecode(String s, String enc) 409 throws UnsupportedEncodingException { 410 boolean needToChange = false; 411 StringBuffer sb = new StringBuffer(); 412 int numChars = s.length(); 413 int i = 0; 414 415 if (enc.length() == 0) { 416 throw new UnsupportedEncodingException ("LzHTTPUtils.urldecode: empty string enc parameter"); 417 } 418 419 while (i < numChars) { 420 char c = s.charAt(i); 421 switch (c) { 422 case '+': 423 sb.append(' '); 424 i++; 425 needToChange = true; 426 break; 427 case '%': 428 436 437 try { 438 439 byte[] bytes = new byte[(numChars-i)/3]; 442 int pos = 0; 443 444 while ( ((i+2) < numChars) && 445 (c=='%')) { 446 bytes[pos++] = 447 (byte)Integer.parseInt(s.substring(i+1,i+3),16); 448 i+= 3; 449 if (i < numChars) 450 c = s.charAt(i); 451 } 452 453 456 if ((i < numChars) && (c=='%')) 457 throw new IllegalArgumentException( 458 "URLDecoder: Incomplete trailing escape (%) pattern"); 459 460 sb.append(new String(bytes, 0, pos, enc)); 461 } catch (NumberFormatException e) { 462 throw new IllegalArgumentException( 463 "URLDecoder: Illegal hex characters in escape (%) pattern - " 464 + e.getMessage()); 465 } 466 needToChange = true; 467 break; 468 default: 469 sb.append(c); 470 i++; 471 break; 472 } 473 } 474 return (needToChange? sb.toString() : s); 475 } 476 477 } 478 | Popular Tags |