001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.protocol.http.servlet; 018 019import java.text.DateFormat; 020import java.text.SimpleDateFormat; 021import java.util.Arrays; 022import java.util.Collections; 023import java.util.Date; 024import java.util.Enumeration; 025import java.util.HashMap; 026import java.util.List; 027import java.util.Locale; 028import java.util.Map; 029 030import javax.servlet.http.HttpServletRequest; 031import javax.servlet.http.HttpServletRequestWrapper; 032 033/** 034 * See <a href="http://code.google.com/p/xebia-france/wiki/XForwardedFilter">XForwardedFilter</a> 035 * 036 * @author Juergen Donnerstag 037 */ 038public class XForwardedRequestWrapper extends HttpServletRequestWrapper 039{ 040 private SimpleDateFormat[] dateFormats = new SimpleDateFormat[] { 041 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), 042 new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), 043 new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) }; 044 045 private Map<String, List<String>> headers; 046 047 private String remoteAddr; 048 049 private String remoteHost; 050 051 private String scheme; 052 053 private boolean secure; 054 055 private int serverPort; 056 057 /** 058 * Construct. 059 * 060 * @param request 061 */ 062 @SuppressWarnings("unchecked") 063 public XForwardedRequestWrapper(final HttpServletRequest request) 064 { 065 super(request); 066 067 remoteAddr = request.getRemoteAddr(); 068 remoteHost = request.getRemoteHost(); 069 scheme = request.getScheme(); 070 secure = request.isSecure(); 071 serverPort = request.getServerPort(); 072 073 headers = new HashMap<String, List<String>>(); 074 Enumeration<?> headerNames = request.getHeaderNames(); 075 while (headerNames.hasMoreElements()) 076 { 077 String header = (String)headerNames.nextElement(); 078 headers.put(header, Collections.list(request.getHeaders(header))); 079 } 080 } 081 082 /** 083 * @see javax.servlet.http.HttpServletRequestWrapper#getDateHeader(java.lang.String) 084 */ 085 @Override 086 public long getDateHeader(final String name) 087 { 088 String value = getHeader(name); 089 if (value == null) 090 { 091 return -1; 092 } 093 094 Date date = null; 095 for (int i = 0; ((i < dateFormats.length) && (date == null)); i++) 096 { 097 DateFormat dateFormat = dateFormats[i]; 098 try 099 { 100 date = dateFormat.parse(value); 101 } 102 catch (Exception ignored) 103 { 104 ; // noop 105 } 106 } 107 108 if (date == null) 109 { 110 throw new IllegalArgumentException(value); 111 } 112 else 113 { 114 return date.getTime(); 115 } 116 } 117 118 /** 119 * @see javax.servlet.http.HttpServletRequestWrapper#getHeader(java.lang.String) 120 */ 121 @Override 122 public String getHeader(final String name) 123 { 124 Map.Entry<String, List<String>> header = getHeaderEntry(name); 125 if (header == null || header.getValue() == null || header.getValue().isEmpty()) 126 { 127 return null; 128 } 129 else 130 { 131 return header.getValue().get(0); 132 } 133 } 134 135 /** 136 * 137 * @param name 138 * @return The map entry for 'name' 139 */ 140 private Map.Entry<String, List<String>> getHeaderEntry(final String name) 141 { 142 for (Map.Entry<String, List<String>> entry : headers.entrySet()) 143 { 144 if (entry.getKey().equalsIgnoreCase(name)) 145 { 146 return entry; 147 } 148 } 149 return null; 150 } 151 152 /** 153 * @see javax.servlet.http.HttpServletRequestWrapper#getHeaderNames() 154 */ 155 @Override 156 public Enumeration<String> getHeaderNames() 157 { 158 return Collections.enumeration(headers.keySet()); 159 } 160 161 /** 162 * @see javax.servlet.http.HttpServletRequestWrapper#getHeaders(java.lang.String) 163 */ 164 @Override 165 public Enumeration<String> getHeaders(final String name) 166 { 167 Map.Entry<String, List<String>> header = getHeaderEntry(name); 168 if (header == null || header.getValue() == null) 169 { 170 return Collections.enumeration(Collections.<String>emptyList()); 171 } 172 else 173 { 174 return Collections.enumeration(header.getValue()); 175 } 176 } 177 178 /** 179 * @see javax.servlet.http.HttpServletRequestWrapper#getIntHeader(java.lang.String) 180 */ 181 @Override 182 public int getIntHeader(final String name) 183 { 184 String value = getHeader(name); 185 if (value == null) 186 { 187 return -1; 188 } 189 else 190 { 191 return Integer.parseInt(value); 192 } 193 } 194 195 /** 196 * @see javax.servlet.ServletRequestWrapper#getRemoteAddr() 197 */ 198 @Override 199 public String getRemoteAddr() 200 { 201 return remoteAddr; 202 } 203 204 /** 205 * @see javax.servlet.ServletRequestWrapper#getRemoteHost() 206 */ 207 @Override 208 public String getRemoteHost() 209 { 210 return remoteHost; 211 } 212 213 /** 214 * @see javax.servlet.ServletRequestWrapper#getScheme() 215 */ 216 @Override 217 public String getScheme() 218 { 219 return scheme; 220 } 221 222 /** 223 * @see javax.servlet.ServletRequestWrapper#getServerPort() 224 */ 225 @Override 226 public int getServerPort() 227 { 228 return serverPort; 229 } 230 231 /** 232 * @see javax.servlet.ServletRequestWrapper#isSecure() 233 */ 234 @Override 235 public boolean isSecure() 236 { 237 return secure; 238 } 239 240 /** 241 * @param name 242 */ 243 public void removeHeader(final String name) 244 { 245 Map.Entry<String, List<String>> header = getHeaderEntry(name); 246 if (header != null) 247 { 248 headers.remove(header.getKey()); 249 } 250 } 251 252 /** 253 * 254 * @param name 255 * @param value 256 */ 257 public void setHeader(final String name, final String value) 258 { 259 List<String> values = Arrays.asList(value); 260 Map.Entry<String, List<String>> header = getHeaderEntry(name); 261 if (header == null) 262 { 263 headers.put(name, values); 264 } 265 else 266 { 267 header.setValue(values); 268 } 269 } 270 271 /** 272 * 273 * @param remoteAddr 274 */ 275 public void setRemoteAddr(final String remoteAddr) 276 { 277 this.remoteAddr = remoteAddr; 278 } 279 280 /** 281 * 282 * @param remoteHost 283 */ 284 public void setRemoteHost(final String remoteHost) 285 { 286 this.remoteHost = remoteHost; 287 } 288 289 /** 290 * 291 * @param scheme 292 */ 293 public void setScheme(final String scheme) 294 { 295 this.scheme = scheme; 296 } 297 298 /** 299 * 300 * @param secure 301 */ 302 public void setSecure(final boolean secure) 303 { 304 this.secure = secure; 305 } 306 307 /** 308 * 309 * @param serverPort 310 */ 311 public void setServerPort(final int serverPort) 312 { 313 this.serverPort = serverPort; 314 } 315}