001
014
015 package com.liferay.portal.resiliency.spi.agent;
016
017 import com.liferay.portal.kernel.io.AutoDeleteFileInputStream;
018 import com.liferay.portal.kernel.resiliency.spi.SPIUtil;
019 import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
020 import com.liferay.portal.kernel.servlet.PersistentHttpServletRequestWrapper;
021 import com.liferay.portal.kernel.servlet.ServletInputStreamAdapter;
022 import com.liferay.portal.kernel.upload.FileItem;
023 import com.liferay.portal.kernel.upload.UploadServletRequest;
024 import com.liferay.portal.kernel.util.ArrayUtil;
025 import com.liferay.portal.kernel.util.ContentTypes;
026 import com.liferay.portal.kernel.util.CookieUtil;
027 import com.liferay.portal.kernel.util.FileUtil;
028 import com.liferay.portal.kernel.util.SetUtil;
029 import com.liferay.portal.kernel.util.StreamUtil;
030 import com.liferay.portal.kernel.util.StringBundler;
031 import com.liferay.portal.kernel.util.StringPool;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.model.Portlet;
034 import com.liferay.portal.theme.ThemeDisplay;
035 import com.liferay.portal.upload.UploadServletRequestImpl;
036 import com.liferay.portal.util.WebKeys;
037
038 import java.io.File;
039 import java.io.FileOutputStream;
040 import java.io.IOException;
041 import java.io.Serializable;
042
043 import java.util.Arrays;
044 import java.util.Collections;
045 import java.util.Enumeration;
046 import java.util.HashMap;
047 import java.util.List;
048 import java.util.Map;
049 import java.util.Set;
050
051 import javax.servlet.ServletInputStream;
052 import javax.servlet.http.Cookie;
053 import javax.servlet.http.HttpServletRequest;
054 import javax.servlet.http.HttpServletRequestWrapper;
055 import javax.servlet.http.HttpSession;
056
057
060 public class SPIAgentRequest extends SPIAgentSerializable {
061
062 public static void populatePortletSessionAttributes(
063 HttpServletRequest request, HttpSession session) {
064
065 if (!SPIUtil.isSPI()) {
066 return;
067 }
068
069 if (request.getAttribute(WebKeys.PORTLET_SESSION) != null) {
070 return;
071 }
072
073 SPIAgentRequest spiAgentRequest = (SPIAgentRequest)request.getAttribute(
074 WebKeys.SPI_AGENT_REQUEST);
075
076 if (spiAgentRequest == null) {
077 return;
078 }
079
080 request.setAttribute(WebKeys.PORTLET_SESSION, session);
081
082 Map<String, Serializable> originalSessionAttributes =
083 spiAgentRequest.originalSessionAttributes;
084
085 Map<String, Serializable> portletSessionAttributes =
086 (Map<String, Serializable>)originalSessionAttributes.remove(
087 WebKeys.PORTLET_SESSION_ATTRIBUTES.concat(
088 spiAgentRequest.servletContextName));
089
090 Set<String> sessionAttributeNames = SetUtil.fromEnumeration(
091 session.getAttributeNames());
092
093 if (portletSessionAttributes != null) {
094 for (Map.Entry<String, Serializable> entry :
095 portletSessionAttributes.entrySet()) {
096
097 session.setAttribute(entry.getKey(), entry.getValue());
098 }
099
100 sessionAttributeNames.removeAll(portletSessionAttributes.keySet());
101 }
102
103 for (String sessionAttributeName : sessionAttributeNames) {
104 session.removeAttribute(sessionAttributeName);
105 }
106 }
107
108 public SPIAgentRequest(HttpServletRequest request) throws IOException {
109 super(
110 ((Portlet)request.getAttribute(
111 WebKeys.SPI_AGENT_PORTLET)).getContextName());
112
113 cookies = request.getCookies();
114 distributedRequestAttributes = extractDistributedRequestAttributes(
115 request, Direction.REQUEST);
116 headerMap = extractRequestHeaders(request);
117 parameterMap = request.getParameterMap();
118 serverName = request.getServerName();
119 serverPort = request.getServerPort();
120
121 String contentType = request.getContentType();
122
123 if ((contentType != null) &&
124 contentType.startsWith(ContentTypes.MULTIPART)) {
125
126 HttpServletRequest currentRequest = request;
127
128 UploadServletRequest uploadServletRequest = null;
129
130 while (currentRequest instanceof HttpServletRequestWrapper) {
131 if (currentRequest instanceof UploadServletRequest) {
132 uploadServletRequest = (UploadServletRequest)currentRequest;
133
134 break;
135 }
136
137 HttpServletRequestWrapper httpServletRequestWrapper =
138 (HttpServletRequestWrapper)currentRequest;
139
140 currentRequest =
141 (HttpServletRequest)httpServletRequestWrapper.getRequest();
142 }
143
144 if (uploadServletRequest == null) {
145 this.contentType = contentType;
146
147 requestBodyFile = FileUtil.createTempFile();
148
149 FileOutputStream fileOutputStream = new FileOutputStream(
150 requestBodyFile);
151
152 try {
153 StreamUtil.transfer(
154 currentRequest.getInputStream(), fileOutputStream,
155 false);
156 }
157 finally {
158 fileOutputStream.close();
159 }
160
161 uploadServletRequest = new UploadServletRequestImpl(
162 new AgentHttpServletRequestWrapper(currentRequest));
163 }
164
165 Map<String, FileItem[]> multipartParameterMap =
166 uploadServletRequest.getMultipartParameterMap();
167 Map<String, List<String>> regularParameterMap =
168 uploadServletRequest.getRegularParameterMap();
169
170 if (!multipartParameterMap.isEmpty()) {
171 this.multipartParameterMap = multipartParameterMap;
172 }
173
174 if (!regularParameterMap.isEmpty()) {
175 this.regularParameterMap = regularParameterMap;
176 }
177 }
178
179 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
180 WebKeys.THEME_DISPLAY);
181
182 if ((themeDisplay != null) && themeDisplay.isAjax()) {
183 parameterMap = new HashMap<String, String[]>(parameterMap);
184
185 parameterMap.put(
186 "portalResiliencyPortletShowFooter",
187 new String[] {StringPool.FALSE});
188 }
189
190 originalSessionAttributes = extractSessionAttributes(request);
191
192 captureThreadLocals();
193 }
194
195 public Map<String, Serializable> getOriginalSessionAttributes() {
196 return originalSessionAttributes;
197 }
198
199 public HttpServletRequest populateRequest(HttpServletRequest request) {
200 request = new AgentHttpServletRequestWrapper(request);
201
202 for (Map.Entry<String, Serializable> entry :
203 distributedRequestAttributes.entrySet()) {
204
205 request.setAttribute(entry.getKey(), entry.getValue());
206 }
207
208 if ((multipartParameterMap != null) || (regularParameterMap != null)) {
209 request = new UploadServletRequestImpl(
210 request, multipartParameterMap, regularParameterMap);
211 }
212
213 restoreThreadLocals();
214
215 return request;
216 }
217
218 public void populateSessionAttributes(HttpSession session) {
219 for (Map.Entry<String, Serializable> entry :
220 originalSessionAttributes.entrySet()) {
221
222 session.setAttribute(entry.getKey(), entry.getValue());
223 }
224 }
225
226 @Override
227 public String toString() {
228 int length = 20 + parameterMap.size() * 4;
229
230 if (cookies != null) {
231 length += cookies.length * 2 - 1;
232 }
233
234 StringBundler sb = new StringBundler(length);
235
236 sb.append("{contentType=");
237 sb.append(contentType);
238 sb.append(", cookies=[");
239
240 if (cookies != null) {
241 for (Cookie cookie : cookies) {
242 sb.append(CookieUtil.toString(cookie));
243 sb.append(", ");
244 }
245
246 sb.setIndex(sb.index() - 1);
247 }
248
249 sb.append("], distributedRequestAttributes=");
250 sb.append(distributedRequestAttributes);
251 sb.append(", headerMap=");
252 sb.append(headerMap);
253 sb.append(", multipartParameterMap=");
254 sb.append(multipartParameterMap);
255 sb.append(", originalSessionAttributes=");
256 sb.append(originalSessionAttributes);
257 sb.append(", parameterMap={");
258
259 for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
260 sb.append(entry.getKey());
261 sb.append("=");
262 sb.append(Arrays.toString(entry.getValue()));
263 sb.append(", ");
264 }
265
266 sb.setIndex(sb.index() - 1);
267
268 sb.append("}, regularParameterMap=");
269 sb.append(regularParameterMap);
270 sb.append(", requestBodyFile=");
271 sb.append(requestBodyFile);
272 sb.append(", serverName=");
273 sb.append(serverName);
274 sb.append(", serverPort=");
275 sb.append(serverPort);
276 sb.append("}");
277
278 return sb.toString();
279 }
280
281 protected String contentType;
282 protected Cookie[] cookies;
283 protected Map<String, Serializable> distributedRequestAttributes;
284 protected Map<String, List<String>> headerMap;
285 protected Map<String, FileItem[]> multipartParameterMap;
286 protected Map<String, Serializable> originalSessionAttributes;
287 protected Map<String, String[]> parameterMap;
288 protected Map<String, List<String>> regularParameterMap;
289 protected File requestBodyFile;
290 protected String serverName;
291 protected int serverPort;
292
293 protected class AgentHttpServletRequestWrapper
294 extends PersistentHttpServletRequestWrapper {
295
296 public AgentHttpServletRequestWrapper(HttpServletRequest request) {
297 super(request);
298 }
299
300 @Override
301 public int getContentLength() {
302 if (requestBodyFile != null) {
303 return (int)requestBodyFile.length();
304 }
305
306 return super.getContentLength();
307 }
308
309 @Override
310 public String getContentType() {
311 if (contentType != null) {
312 return contentType;
313 }
314
315 return super.getContentType();
316 }
317
318 @Override
319 public Cookie[] getCookies() {
320 return cookies;
321 }
322
323 @Override
324 public String getHeader(String name) {
325 List<String> values = headerMap.get(StringUtil.toLowerCase(name));
326
327 if ((values == null) || values.isEmpty()) {
328 return null;
329 }
330
331 return values.get(0);
332 }
333
334 @Override
335 public Enumeration<String> getHeaderNames() {
336 return Collections.enumeration(headerMap.keySet());
337 }
338
339 @Override
340 public Enumeration<String> getHeaders(String name) {
341 List<String> values = headerMap.get(StringUtil.toLowerCase(name));
342
343 if (values == null) {
344 values = Collections.emptyList();
345 }
346
347 return Collections.enumeration(values);
348 }
349
350 @Override
351 public ServletInputStream getInputStream() throws IOException {
352 if (requestBodyFile != null) {
353 return new ServletInputStreamAdapter(
354 new AutoDeleteFileInputStream(requestBodyFile));
355 }
356
357 return super.getInputStream();
358 }
359
360 @Override
361 public String getParameter(String name) {
362 String[] values = parameterMap.get(name);
363
364 if (ArrayUtil.isNotEmpty(values)) {
365 return values[0];
366 }
367 else {
368 return null;
369 }
370 }
371
372 @Override
373 public Map<String, String[]> getParameterMap() {
374 return parameterMap;
375 }
376
377 @Override
378 public Enumeration<String> getParameterNames() {
379 return Collections.enumeration(parameterMap.keySet());
380 }
381
382 @Override
383 public String[] getParameterValues(String name) {
384 return parameterMap.get(name);
385 }
386
387 @Override
388 public String getServerName() {
389 return serverName;
390 }
391
392 @Override
393 public int getServerPort() {
394 return serverPort;
395 }
396
397 }
398
399 }