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 Cookie[] cookies = request.getCookies();
114
115 if (cookies != null) {
116 cookiesBytes = new byte[cookies.length][];
117
118 for (int i = 0; i < cookies.length; i++) {
119 cookiesBytes[i] = CookieUtil.serialize(cookies[i]);
120 }
121 }
122
123 distributedRequestAttributes = extractDistributedRequestAttributes(
124 request, Direction.REQUEST);
125 headerMap = extractRequestHeaders(request);
126 parameterMap = new HashMap<String, String[]>(request.getParameterMap());
127 remoteAddr = request.getRemoteAddr();
128 remoteHost = request.getRemoteHost();
129 remotePort = request.getRemotePort();
130 remoteUser = request.getRemoteUser();
131 serverName = request.getServerName();
132 serverPort = request.getServerPort();
133
134 String contentType = request.getContentType();
135
136 if ((contentType != null) &&
137 contentType.startsWith(ContentTypes.MULTIPART)) {
138
139 HttpServletRequest currentRequest = request;
140
141 UploadServletRequest uploadServletRequest = null;
142
143 while (currentRequest instanceof HttpServletRequestWrapper) {
144 if (currentRequest instanceof UploadServletRequest) {
145 uploadServletRequest = (UploadServletRequest)currentRequest;
146
147 break;
148 }
149
150 HttpServletRequestWrapper httpServletRequestWrapper =
151 (HttpServletRequestWrapper)currentRequest;
152
153 currentRequest =
154 (HttpServletRequest)httpServletRequestWrapper.getRequest();
155 }
156
157 if (uploadServletRequest == null) {
158 this.contentType = contentType;
159
160 requestBodyFile = FileUtil.createTempFile();
161
162 FileOutputStream fileOutputStream = new FileOutputStream(
163 requestBodyFile);
164
165 try {
166 StreamUtil.transfer(
167 currentRequest.getInputStream(), fileOutputStream,
168 false);
169 }
170 finally {
171 fileOutputStream.close();
172 }
173
174 uploadServletRequest = new UploadServletRequestImpl(
175 new AgentHttpServletRequestWrapper(currentRequest));
176 }
177
178 Map<String, FileItem[]> multipartParameterMap =
179 uploadServletRequest.getMultipartParameterMap();
180 Map<String, List<String>> regularParameterMap =
181 uploadServletRequest.getRegularParameterMap();
182
183 if (!multipartParameterMap.isEmpty()) {
184 this.multipartParameterMap = multipartParameterMap;
185 }
186
187 if (!regularParameterMap.isEmpty()) {
188 this.regularParameterMap = regularParameterMap;
189 }
190 }
191
192 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
193 WebKeys.THEME_DISPLAY);
194
195 if ((themeDisplay != null) && themeDisplay.isAjax()) {
196 parameterMap = new HashMap<String, String[]>(parameterMap);
197
198 parameterMap.put(
199 "portalResiliencyPortletShowFooter",
200 new String[] {StringPool.FALSE});
201 }
202
203 originalSessionAttributes = extractSessionAttributes(request);
204
205 captureThreadLocals();
206 }
207
208 public Map<String, Serializable> getOriginalSessionAttributes() {
209 return originalSessionAttributes;
210 }
211
212 public HttpServletRequest populateRequest(HttpServletRequest request) {
213 request = new AgentHttpServletRequestWrapper(request);
214
215 for (Map.Entry<String, Serializable> entry :
216 distributedRequestAttributes.entrySet()) {
217
218 request.setAttribute(entry.getKey(), entry.getValue());
219 }
220
221 if ((multipartParameterMap != null) || (regularParameterMap != null)) {
222 request = new UploadServletRequestImpl(
223 request, multipartParameterMap, regularParameterMap);
224 }
225
226 restoreThreadLocals();
227
228 return request;
229 }
230
231 public void populateSessionAttributes(HttpSession session) {
232 for (Map.Entry<String, Serializable> entry :
233 originalSessionAttributes.entrySet()) {
234
235 session.setAttribute(entry.getKey(), entry.getValue());
236 }
237 }
238
239 @Override
240 public String toString() {
241 int length = 20 + parameterMap.size() * 4;
242
243 if (cookiesBytes != null) {
244 length += cookiesBytes.length * 2 - 1;
245 }
246
247 StringBundler sb = new StringBundler(length);
248
249 sb.append("{contentType=");
250 sb.append(contentType);
251 sb.append(", cookies=[");
252
253 if (cookiesBytes != null) {
254 for (byte[] cookieBytes : cookiesBytes) {
255 Cookie cookie = CookieUtil.deserialize(cookieBytes);
256
257 sb.append(CookieUtil.toString(cookie));
258 sb.append(", ");
259 }
260
261 sb.setIndex(sb.index() - 1);
262 }
263
264 sb.append("], distributedRequestAttributes=");
265 sb.append(distributedRequestAttributes);
266 sb.append(", headerMap=");
267 sb.append(headerMap);
268 sb.append(", multipartParameterMap=");
269 sb.append(multipartParameterMap);
270 sb.append(", originalSessionAttributes=");
271 sb.append(originalSessionAttributes);
272 sb.append(", parameterMap={");
273
274 for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
275 sb.append(entry.getKey());
276 sb.append("=");
277 sb.append(Arrays.toString(entry.getValue()));
278 sb.append(", ");
279 }
280
281 sb.setIndex(sb.index() - 1);
282
283 sb.append("}, regularParameterMap=");
284 sb.append(regularParameterMap);
285 sb.append(", requestBodyFile=");
286 sb.append(requestBodyFile);
287 sb.append(", serverName=");
288 sb.append(serverName);
289 sb.append(", serverPort=");
290 sb.append(serverPort);
291 sb.append("}");
292
293 return sb.toString();
294 }
295
296 protected String contentType;
297 protected byte[][] cookiesBytes;
298 protected Map<String, Serializable> distributedRequestAttributes;
299 protected Map<String, List<String>> headerMap;
300 protected Map<String, FileItem[]> multipartParameterMap;
301 protected Map<String, Serializable> originalSessionAttributes;
302 protected Map<String, String[]> parameterMap;
303 protected Map<String, List<String>> regularParameterMap;
304 protected String remoteAddr;
305 protected String remoteHost;
306 protected int remotePort;
307 protected String remoteUser;
308 protected File requestBodyFile;
309 protected String serverName;
310 protected int serverPort;
311
312 protected class AgentHttpServletRequestWrapper
313 extends PersistentHttpServletRequestWrapper {
314
315 public AgentHttpServletRequestWrapper(HttpServletRequest request) {
316 super(request);
317 }
318
319 @Override
320 public int getContentLength() {
321 if (requestBodyFile != null) {
322 return (int)requestBodyFile.length();
323 }
324
325 return super.getContentLength();
326 }
327
328 @Override
329 public String getContentType() {
330 if (contentType != null) {
331 return contentType;
332 }
333
334 return super.getContentType();
335 }
336
337 @Override
338 public Cookie[] getCookies() {
339 if (cookiesBytes == null) {
340 return null;
341 }
342
343 Cookie[] cookies = new Cookie[cookiesBytes.length];
344
345 for (int i = 0; i < cookies.length; i++) {
346 cookies[i] = CookieUtil.deserialize(cookiesBytes[i]);
347 }
348
349 return cookies;
350 }
351
352 @Override
353 public String getHeader(String name) {
354 List<String> values = headerMap.get(StringUtil.toLowerCase(name));
355
356 if ((values == null) || values.isEmpty()) {
357 return null;
358 }
359
360 return values.get(0);
361 }
362
363 @Override
364 public Enumeration<String> getHeaderNames() {
365 return Collections.enumeration(headerMap.keySet());
366 }
367
368 @Override
369 public Enumeration<String> getHeaders(String name) {
370 List<String> values = headerMap.get(StringUtil.toLowerCase(name));
371
372 if (values == null) {
373 values = Collections.emptyList();
374 }
375
376 return Collections.enumeration(values);
377 }
378
379 @Override
380 public ServletInputStream getInputStream() throws IOException {
381 if (requestBodyFile != null) {
382 return new ServletInputStreamAdapter(
383 new AutoDeleteFileInputStream(requestBodyFile));
384 }
385
386 return super.getInputStream();
387 }
388
389 @Override
390 public String getParameter(String name) {
391 String[] values = parameterMap.get(name);
392
393 if (ArrayUtil.isNotEmpty(values)) {
394 return values[0];
395 }
396 else {
397 return null;
398 }
399 }
400
401 @Override
402 public Map<String, String[]> getParameterMap() {
403 return parameterMap;
404 }
405
406 @Override
407 public Enumeration<String> getParameterNames() {
408 return Collections.enumeration(parameterMap.keySet());
409 }
410
411 @Override
412 public String[] getParameterValues(String name) {
413 return parameterMap.get(name);
414 }
415
416 @Override
417 public String getRemoteAddr() {
418 return remoteAddr;
419 }
420
421 @Override
422 public String getRemoteHost() {
423 return remoteHost;
424 }
425
426 @Override
427 public int getRemotePort() {
428 return remotePort;
429 }
430
431 @Override
432 public String getRemoteUser() {
433 return remoteUser;
434 }
435
436 @Override
437 public String getServerName() {
438 return serverName;
439 }
440
441 @Override
442 public int getServerPort() {
443 return serverPort;
444 }
445
446 }
447
448 }