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.model.Portlet;
019 import com.liferay.portal.kernel.resiliency.spi.SPIUtil;
020 import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
021 import com.liferay.portal.kernel.servlet.PersistentHttpServletRequestWrapper;
022 import com.liferay.portal.kernel.servlet.ServletInputStreamAdapter;
023 import com.liferay.portal.kernel.theme.ThemeDisplay;
024 import com.liferay.portal.kernel.upload.FileItem;
025 import com.liferay.portal.kernel.upload.UploadServletRequest;
026 import com.liferay.portal.kernel.util.ArrayUtil;
027 import com.liferay.portal.kernel.util.ContentTypes;
028 import com.liferay.portal.kernel.util.CookieUtil;
029 import com.liferay.portal.kernel.util.FileUtil;
030 import com.liferay.portal.kernel.util.SetUtil;
031 import com.liferay.portal.kernel.util.StreamUtil;
032 import com.liferay.portal.kernel.util.StringBundler;
033 import com.liferay.portal.kernel.util.StringPool;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.kernel.util.WebKeys;
036 import com.liferay.portal.upload.UploadServletRequestImpl;
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<>(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 StreamUtil.transfer(
163 StreamUtil.uncloseable(currentRequest.getInputStream()),
164 new FileOutputStream(requestBodyFile));
165
166 uploadServletRequest = new UploadServletRequestImpl(
167 new AgentHttpServletRequestWrapper(currentRequest));
168 }
169
170 Map<String, FileItem[]> multipartParameterMap =
171 uploadServletRequest.getMultipartParameterMap();
172 Map<String, List<String>> regularParameterMap =
173 uploadServletRequest.getRegularParameterMap();
174
175 if (!multipartParameterMap.isEmpty()) {
176 this.multipartParameterMap = multipartParameterMap;
177 }
178
179 if (!regularParameterMap.isEmpty()) {
180 this.regularParameterMap = regularParameterMap;
181 }
182 }
183
184 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
185 WebKeys.THEME_DISPLAY);
186
187 if ((themeDisplay != null) && themeDisplay.isAjax()) {
188 parameterMap = new HashMap<>(parameterMap);
189
190 parameterMap.put(
191 "portalResiliencyPortletShowFooter",
192 new String[] {StringPool.FALSE});
193 }
194
195 originalSessionAttributes = extractSessionAttributes(request);
196
197 captureThreadLocals();
198 }
199
200 public Map<String, Serializable> getOriginalSessionAttributes() {
201 return originalSessionAttributes;
202 }
203
204 public HttpServletRequest populateRequest(HttpServletRequest request) {
205 request = new AgentHttpServletRequestWrapper(request);
206
207 for (Map.Entry<String, Serializable> entry :
208 distributedRequestAttributes.entrySet()) {
209
210 request.setAttribute(entry.getKey(), entry.getValue());
211 }
212
213 if ((multipartParameterMap != null) || (regularParameterMap != null)) {
214 request = new UploadServletRequestImpl(
215 request, multipartParameterMap, regularParameterMap);
216 }
217
218 restoreThreadLocals();
219
220 return request;
221 }
222
223 public void populateSessionAttributes(HttpSession session) {
224 for (Map.Entry<String, Serializable> entry :
225 originalSessionAttributes.entrySet()) {
226
227 session.setAttribute(entry.getKey(), entry.getValue());
228 }
229 }
230
231 @Override
232 public String toString() {
233 int length = 20 + parameterMap.size() * 4;
234
235 if (cookiesBytes != null) {
236 length += cookiesBytes.length * 2 - 1;
237 }
238
239 StringBundler sb = new StringBundler(length);
240
241 sb.append("{contentType=");
242 sb.append(contentType);
243 sb.append(", cookies=[");
244
245 if (cookiesBytes != null) {
246 for (byte[] cookieBytes : cookiesBytes) {
247 Cookie cookie = CookieUtil.deserialize(cookieBytes);
248
249 sb.append(CookieUtil.toString(cookie));
250 sb.append(", ");
251 }
252
253 sb.setIndex(sb.index() - 1);
254 }
255
256 sb.append("], distributedRequestAttributes=");
257 sb.append(distributedRequestAttributes);
258 sb.append(", headerMap=");
259 sb.append(headerMap);
260 sb.append(", multipartParameterMap=");
261 sb.append(multipartParameterMap);
262 sb.append(", originalSessionAttributes=");
263 sb.append(originalSessionAttributes);
264 sb.append(", parameterMap={");
265
266 for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
267 sb.append(entry.getKey());
268 sb.append("=");
269 sb.append(Arrays.toString(entry.getValue()));
270 sb.append(", ");
271 }
272
273 sb.setIndex(sb.index() - 1);
274
275 sb.append("}, regularParameterMap=");
276 sb.append(regularParameterMap);
277 sb.append(", requestBodyFile=");
278 sb.append(requestBodyFile);
279 sb.append(", serverName=");
280 sb.append(serverName);
281 sb.append(", serverPort=");
282 sb.append(serverPort);
283 sb.append("}");
284
285 return sb.toString();
286 }
287
288 protected String contentType;
289 protected byte[][] cookiesBytes;
290 protected Map<String, Serializable> distributedRequestAttributes;
291 protected Map<String, List<String>> headerMap;
292 protected Map<String, FileItem[]> multipartParameterMap;
293 protected Map<String, Serializable> originalSessionAttributes;
294 protected Map<String, String[]> parameterMap;
295 protected Map<String, List<String>> regularParameterMap;
296 protected String remoteAddr;
297 protected String remoteHost;
298 protected int remotePort;
299 protected String remoteUser;
300 protected File requestBodyFile;
301 protected String serverName;
302 protected int serverPort;
303
304 protected class AgentHttpServletRequestWrapper
305 extends PersistentHttpServletRequestWrapper {
306
307 public AgentHttpServletRequestWrapper(HttpServletRequest request) {
308 super(request);
309 }
310
311 @Override
312 public int getContentLength() {
313 if (requestBodyFile != null) {
314 return (int)requestBodyFile.length();
315 }
316
317 return super.getContentLength();
318 }
319
320 @Override
321 public String getContentType() {
322 if (contentType != null) {
323 return contentType;
324 }
325
326 return super.getContentType();
327 }
328
329 @Override
330 public Cookie[] getCookies() {
331 if (cookiesBytes == null) {
332 return null;
333 }
334
335 Cookie[] cookies = new Cookie[cookiesBytes.length];
336
337 for (int i = 0; i < cookies.length; i++) {
338 cookies[i] = CookieUtil.deserialize(cookiesBytes[i]);
339 }
340
341 return cookies;
342 }
343
344 @Override
345 public String getHeader(String name) {
346 List<String> values = headerMap.get(StringUtil.toLowerCase(name));
347
348 if ((values == null) || values.isEmpty()) {
349 return null;
350 }
351
352 return values.get(0);
353 }
354
355 @Override
356 public Enumeration<String> getHeaderNames() {
357 return Collections.enumeration(headerMap.keySet());
358 }
359
360 @Override
361 public Enumeration<String> getHeaders(String name) {
362 List<String> values = headerMap.get(StringUtil.toLowerCase(name));
363
364 if (values == null) {
365 values = Collections.emptyList();
366 }
367
368 return Collections.enumeration(values);
369 }
370
371 @Override
372 public ServletInputStream getInputStream() throws IOException {
373 if (requestBodyFile != null) {
374 return new ServletInputStreamAdapter(
375 new AutoDeleteFileInputStream(requestBodyFile));
376 }
377
378 return super.getInputStream();
379 }
380
381 @Override
382 public String getParameter(String name) {
383 String[] values = parameterMap.get(name);
384
385 if (ArrayUtil.isNotEmpty(values)) {
386 return values[0];
387 }
388 else {
389 return null;
390 }
391 }
392
393 @Override
394 public Map<String, String[]> getParameterMap() {
395 return parameterMap;
396 }
397
398 @Override
399 public Enumeration<String> getParameterNames() {
400 return Collections.enumeration(parameterMap.keySet());
401 }
402
403 @Override
404 public String[] getParameterValues(String name) {
405 return parameterMap.get(name);
406 }
407
408 @Override
409 public String getRemoteAddr() {
410 return remoteAddr;
411 }
412
413 @Override
414 public String getRemoteHost() {
415 return remoteHost;
416 }
417
418 @Override
419 public int getRemotePort() {
420 return remotePort;
421 }
422
423 @Override
424 public String getRemoteUser() {
425 return remoteUser;
426 }
427
428 @Override
429 public String getServerName() {
430 return serverName;
431 }
432
433 @Override
434 public int getServerPort() {
435 return serverPort;
436 }
437
438 }
439
440 }