001// Copyright 2006-2013 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.internal.services; 016 017import org.apache.tapestry5.ioc.internal.util.InternalUtils; 018import org.apache.tapestry5.services.Request; 019import org.apache.tapestry5.services.Session; 020 021import javax.servlet.http.HttpServletRequest; 022import java.io.UnsupportedEncodingException; 023import java.util.List; 024import java.util.Locale; 025 026/** 027 * Basic implementation of {@link org.apache.tapestry5.services.Request} that wraps around an 028 * {@link javax.servlet.http.HttpServletRequest}. This is not threadsafe, nor should it need to be (each Request is 029 * handled by its own Thread). 030 */ 031public class RequestImpl implements Request 032{ 033 static final String REQUESTED_WITH_HEADER = "X-Requested-With"; 034 035 static final String XML_HTTP_REQUEST = "XMLHttpRequest"; 036 037 static final String X_FORWARDED_PROTO_HEADER = "X-Forwarded-Proto"; 038 static final String X_FORWARDED_PROTO_HTTPS = "https"; 039 040 private final HttpServletRequest request; 041 042 private final String requestEncoding; 043 044 private final TapestrySessionFactory sessionFactory; 045 046 private boolean encodingSet; 047 048 private Session session; 049 050 public RequestImpl( 051 HttpServletRequest request, 052 String requestEncoding, 053 TapestrySessionFactory sessionFactory) 054 { 055 this.request = request; 056 this.requestEncoding = requestEncoding; 057 this.sessionFactory = sessionFactory; 058 } 059 060 public List<String> getParameterNames() 061 { 062 setupEncoding(); 063 064 return InternalUtils.toList(request.getParameterNames()); 065 } 066 067 public List<String> getHeaderNames() 068 { 069 return InternalUtils.toList(request.getHeaderNames()); 070 } 071 072 public String getParameter(String name) 073 { 074 setupEncoding(); 075 076 return request.getParameter(name); 077 } 078 079 public String[] getParameters(String name) 080 { 081 setupEncoding(); 082 083 return request.getParameterValues(name); 084 } 085 086 public String getHeader(String name) 087 { 088 return request.getHeader(name); 089 } 090 091 public String getPath() 092 { 093 String pathInfo = request.getPathInfo(); 094 095 if (pathInfo == null) 096 return request.getServletPath(); 097 098 // Websphere 6.1 is a bit wonky (see TAPESTRY-1713), and tends to return the empty string 099 // for the servlet path, and return the true path in pathInfo. 100 101 return pathInfo.length() == 0 ? "/" : pathInfo; 102 } 103 104 public String getContextPath() 105 { 106 return request.getContextPath(); 107 } 108 109 110 public boolean isSessionInvalidated() 111 { 112 // Double check to ensure that the session exists, but don't create it. 113 if (session == null) 114 { 115 session = sessionFactory.getSession(false); 116 } 117 118 return session != null && session.isInvalidated(); 119 } 120 121 public Session getSession(boolean create) 122 { 123 if (session != null && session.isInvalidated()) 124 { 125 session = null; 126 } 127 128 if (session == null) 129 { 130 // TAP5-1489 - Re-storage of session attributes at end of request should be configurable 131 session = sessionFactory.getSession(create); 132 } 133 134 return session; 135 } 136 137 public Locale getLocale() 138 { 139 return request.getLocale(); 140 } 141 142 public long getDateHeader(String name) 143 { 144 return request.getDateHeader(name); 145 } 146 147 private void setupEncoding() 148 { 149 if (encodingSet) 150 return; 151 152 try 153 { 154 request.setCharacterEncoding(requestEncoding); 155 } catch (UnsupportedEncodingException ex) 156 { 157 throw new RuntimeException(ex); 158 } 159 160 encodingSet = true; 161 } 162 163 public boolean isXHR() 164 { 165 return XML_HTTP_REQUEST.equals(request.getHeader(REQUESTED_WITH_HEADER)); 166 } 167 168 public boolean isSecure() 169 { 170 return request.isSecure() || 171 X_FORWARDED_PROTO_HTTPS.equals(request.getHeader(X_FORWARDED_PROTO_HEADER)); 172 } 173 174 public boolean isRequestedSessionIdValid() 175 { 176 return request.isRequestedSessionIdValid(); 177 } 178 179 public Object getAttribute(String name) 180 { 181 return request.getAttribute(name); 182 } 183 184 public List<String> getAttributeNames() 185 { 186 setupEncoding(); 187 188 return InternalUtils.toList(request.getAttributeNames()); 189 } 190 191 public void setAttribute(String name, Object value) 192 { 193 request.setAttribute(name, value); 194 } 195 196 public String getMethod() 197 { 198 return request.getMethod(); 199 } 200 201 public String getServerName() 202 { 203 return request.getServerName(); 204 } 205 206 public int getLocalPort() 207 { 208 return request.getLocalPort(); 209 } 210 211 /** 212 * @since 5.2.5 213 */ 214 public int getServerPort() 215 { 216 return request.getServerPort(); 217 } 218 219 public String getRemoteHost() 220 { 221 return request.getRemoteHost(); 222 } 223 224}