001
014
015 package com.liferay.portal.webserver;
016
017 import com.liferay.portal.NoSuchGroupException;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.image.ImageBag;
021 import com.liferay.portal.kernel.image.ImageToolUtil;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.repository.RepositoryException;
025 import com.liferay.portal.kernel.repository.model.FileEntry;
026 import com.liferay.portal.kernel.repository.model.FileVersion;
027 import com.liferay.portal.kernel.repository.model.Folder;
028 import com.liferay.portal.kernel.servlet.HttpHeaders;
029 import com.liferay.portal.kernel.servlet.PortalSessionThreadLocal;
030 import com.liferay.portal.kernel.servlet.Range;
031 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
032 import com.liferay.portal.kernel.template.Template;
033 import com.liferay.portal.kernel.template.TemplateContextType;
034 import com.liferay.portal.kernel.template.TemplateManager;
035 import com.liferay.portal.kernel.template.TemplateManagerUtil;
036 import com.liferay.portal.kernel.template.TemplateResource;
037 import com.liferay.portal.kernel.template.URLTemplateResource;
038 import com.liferay.portal.kernel.util.CharPool;
039 import com.liferay.portal.kernel.util.ContentTypes;
040 import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
041 import com.liferay.portal.kernel.util.FileUtil;
042 import com.liferay.portal.kernel.util.GetterUtil;
043 import com.liferay.portal.kernel.util.HttpUtil;
044 import com.liferay.portal.kernel.util.MimeTypesUtil;
045 import com.liferay.portal.kernel.util.ParamUtil;
046 import com.liferay.portal.kernel.util.ReleaseInfo;
047 import com.liferay.portal.kernel.util.SetUtil;
048 import com.liferay.portal.kernel.util.StringPool;
049 import com.liferay.portal.kernel.util.StringUtil;
050 import com.liferay.portal.kernel.util.Validator;
051 import com.liferay.portal.kernel.util.Validator_IW;
052 import com.liferay.portal.kernel.webdav.WebDAVUtil;
053 import com.liferay.portal.kernel.workflow.WorkflowConstants;
054 import com.liferay.portal.model.Company;
055 import com.liferay.portal.model.Group;
056 import com.liferay.portal.model.Image;
057 import com.liferay.portal.model.ImageConstants;
058 import com.liferay.portal.model.User;
059 import com.liferay.portal.model.impl.ImageImpl;
060 import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
061 import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
062 import com.liferay.portal.security.auth.PrincipalException;
063 import com.liferay.portal.security.auth.PrincipalThreadLocal;
064 import com.liferay.portal.security.permission.ActionKeys;
065 import com.liferay.portal.security.permission.PermissionChecker;
066 import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
067 import com.liferay.portal.security.permission.PermissionThreadLocal;
068 import com.liferay.portal.service.CompanyLocalServiceUtil;
069 import com.liferay.portal.service.GroupLocalServiceUtil;
070 import com.liferay.portal.service.ImageLocalServiceUtil;
071 import com.liferay.portal.service.ImageServiceUtil;
072 import com.liferay.portal.service.UserLocalServiceUtil;
073 import com.liferay.portal.theme.ThemeDisplay;
074 import com.liferay.portal.util.Portal;
075 import com.liferay.portal.util.PortalUtil;
076 import com.liferay.portal.util.PortletKeys;
077 import com.liferay.portal.util.PropsValues;
078 import com.liferay.portal.util.WebKeys;
079 import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
080 import com.liferay.portlet.documentlibrary.NoSuchFolderException;
081 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
082 import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
083 import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
084 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
085 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
086 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
087 import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
088 import com.liferay.portlet.documentlibrary.service.DLFileEntryMetadataLocalServiceUtil;
089 import com.liferay.portlet.documentlibrary.service.DLFileEntryServiceUtil;
090 import com.liferay.portlet.documentlibrary.util.AudioProcessorUtil;
091 import com.liferay.portlet.documentlibrary.util.DLUtil;
092 import com.liferay.portlet.documentlibrary.util.DocumentConversionUtil;
093 import com.liferay.portlet.documentlibrary.util.ImageProcessorUtil;
094 import com.liferay.portlet.documentlibrary.util.PDFProcessor;
095 import com.liferay.portlet.documentlibrary.util.PDFProcessorUtil;
096 import com.liferay.portlet.documentlibrary.util.VideoProcessor;
097 import com.liferay.portlet.documentlibrary.util.VideoProcessorUtil;
098 import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
099 import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
100 import com.liferay.portlet.dynamicdatamapping.storage.Field;
101 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
102 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
103 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
104
105 import java.awt.image.RenderedImage;
106
107 import java.io.File;
108 import java.io.FileInputStream;
109 import java.io.IOException;
110 import java.io.InputStream;
111
112 import java.net.URL;
113
114 import java.text.Format;
115
116 import java.util.ArrayList;
117 import java.util.Date;
118 import java.util.List;
119 import java.util.Set;
120
121 import javax.servlet.ServletConfig;
122 import javax.servlet.ServletException;
123 import javax.servlet.http.HttpServlet;
124 import javax.servlet.http.HttpServletRequest;
125 import javax.servlet.http.HttpServletResponse;
126 import javax.servlet.http.HttpSession;
127
128
132 public class WebServerServlet extends HttpServlet {
133
134
137 public static boolean hasFiles(HttpServletRequest request) {
138 try {
139
140
141
142
143 User user = _getUser(request);
144
145 String path = HttpUtil.fixPath(request.getPathInfo());
146
147 String[] pathArray = StringUtil.split(path, CharPool.SLASH);
148
149 if (pathArray.length == 0) {
150 return true;
151 }
152 else if (_PATH_DDM.equals(pathArray[0])) {
153 _checkDDMRecord(pathArray);
154 }
155 else if (Validator.isNumber(pathArray[0])) {
156 _checkFileEntry(pathArray);
157 }
158 else {
159 long groupId = _getGroupId(user.getCompanyId(), pathArray[0]);
160 long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
161
162 for (int i = 1; i < pathArray.length; i++) {
163 try {
164 Folder folder = DLAppLocalServiceUtil.getFolder(
165 groupId, folderId, pathArray[i]);
166
167 folderId = folder.getFolderId();
168 }
169 catch (NoSuchFolderException nsfe) {
170 if (i != (pathArray.length - 1)) {
171 return false;
172 }
173
174 pathArray = new String[] {
175 String.valueOf(groupId), String.valueOf(folderId),
176 pathArray[i]
177 };
178
179 _checkFileEntry(pathArray);
180 }
181 }
182 }
183 }
184 catch (Exception e) {
185 return false;
186 }
187
188 return true;
189 }
190
191 @Override
192 public void init(ServletConfig servletConfig) throws ServletException {
193 super.init(servletConfig);
194
195 _lastModified = GetterUtil.getBoolean(
196 servletConfig.getInitParameter("last_modified"), true);
197
198 Class<?> clazz = getClass();
199
200 ClassLoader classLoader = clazz.getClassLoader();
201
202 String templateId =
203 "com/liferay/portal/webserver/dependencies/template.ftl";
204
205 URL url = classLoader.getResource(templateId);
206
207 _templateResource = new URLTemplateResource(templateId, url);
208 }
209
210 @Override
211 public void service(
212 HttpServletRequest request, HttpServletResponse response)
213 throws IOException, ServletException {
214
215 User user = null;
216
217 try {
218 user = _getUser(request);
219
220 PrincipalThreadLocal.setName(user.getUserId());
221 PrincipalThreadLocal.setPassword(
222 PortalUtil.getUserPassword(request));
223
224 PermissionChecker permissionChecker =
225 PermissionCheckerFactoryUtil.create(user);
226
227 PermissionThreadLocal.setPermissionChecker(permissionChecker);
228
229 if (_lastModified) {
230 long lastModified = getLastModified(request);
231
232 if (lastModified > 0) {
233 long ifModifiedSince = request.getDateHeader(
234 HttpHeaders.IF_MODIFIED_SINCE);
235
236 if ((ifModifiedSince > 0) &&
237 (ifModifiedSince == lastModified)) {
238
239 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
240
241 return;
242 }
243 }
244
245 if (lastModified > 0) {
246 response.setDateHeader(
247 HttpHeaders.LAST_MODIFIED, lastModified);
248 }
249 }
250
251 String path = HttpUtil.fixPath(request.getPathInfo());
252 String[] pathArray = StringUtil.split(path, CharPool.SLASH);
253
254 if (pathArray.length == 0) {
255 sendGroups(
256 response, user,
257 request.getServletPath() + StringPool.SLASH + path);
258 }
259 else {
260 if (_PATH_DDM.equals(pathArray[0])) {
261 sendDDMRecordFile(request, response, pathArray);
262 }
263 else if (Validator.isNumber(pathArray[0])) {
264 sendFile(request, response, user, pathArray);
265 }
266 else {
267 if (isLegacyImageGalleryImageId(request, response)) {
268 return;
269 }
270
271 Image image = getImage(request, true);
272
273 if (image != null) {
274 writeImage(image, request, response);
275 }
276 else {
277 sendDocumentLibrary(
278 request, response, user,
279 request.getServletPath() + StringPool.SLASH + path,
280 pathArray);
281 }
282 }
283 }
284 }
285 catch (NoSuchFileEntryException nsfee) {
286 PortalUtil.sendError(
287 HttpServletResponse.SC_NOT_FOUND, nsfee, request, response);
288 }
289 catch (PrincipalException pe) {
290 processPrincipalException(pe, user, request, response);
291 }
292 catch (Exception e) {
293 PortalUtil.sendError(e, request, response);
294 }
295 }
296
297 protected Image convertFileEntry(boolean smallImage, FileEntry fileEntry)
298 throws PortalException, SystemException {
299
300 try {
301 Image image = new ImageImpl();
302
303 image.setModifiedDate(fileEntry.getModifiedDate());
304
305 InputStream is = null;
306
307 if (smallImage) {
308 is = ImageProcessorUtil.getThumbnailAsStream(
309 fileEntry.getFileVersion(), 0);
310 }
311 else {
312 is = fileEntry.getContentStream();
313 }
314
315 byte[] bytes = FileUtil.getBytes(is);
316
317 image.setTextObj(bytes);
318
319 image.setType(fileEntry.getExtension());
320
321 return image;
322 }
323 catch (PortalException pe) {
324 throw pe;
325 }
326 catch (SystemException se) {
327 throw se;
328 }
329 catch (Exception e) {
330 throw new SystemException(e);
331 }
332 }
333
334 protected Image getDefaultImage(HttpServletRequest request, long imageId) {
335 String path = GetterUtil.getString(request.getPathInfo());
336
337 if (path.startsWith("/company_logo") ||
338 path.startsWith("/layout_set_logo") || path.startsWith("/logo")) {
339
340 return ImageLocalServiceUtil.getDefaultCompanyLogo();
341 }
342 else if (path.startsWith("/organization_logo")) {
343 return ImageLocalServiceUtil.getDefaultOrganizationLogo();
344 }
345 else if (path.startsWith("/user_female_portrait")) {
346 return ImageLocalServiceUtil.getDefaultUserFemalePortrait();
347 }
348 else if (path.startsWith("/user_male_portrait")) {
349 return ImageLocalServiceUtil.getDefaultUserMalePortrait();
350 }
351 else if (path.startsWith("/user_portrait")) {
352 return ImageLocalServiceUtil.getDefaultUserMalePortrait();
353 }
354 else {
355 return null;
356 }
357 }
358
359 protected FileEntry getFileEntry(String[] pathArray) throws Exception {
360 if (pathArray.length == 1) {
361 long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);
362
363 DLFileShortcut dlFileShortcut = DLAppServiceUtil.getFileShortcut(
364 dlFileShortcutId);
365
366 return DLAppServiceUtil.getFileEntry(
367 dlFileShortcut.getToFileEntryId());
368 }
369 else if (pathArray.length == 2) {
370 long groupId = GetterUtil.getLong(pathArray[0]);
371
372 return DLAppServiceUtil.getFileEntryByUuidAndGroupId(
373 pathArray[1], groupId);
374 }
375 else if (pathArray.length == 3) {
376 long groupId = GetterUtil.getLong(pathArray[0]);
377 long folderId = GetterUtil.getLong(pathArray[1]);
378 String fileName = HttpUtil.decodeURL(pathArray[2]);
379
380 if (fileName.contains(StringPool.QUESTION)) {
381 fileName = fileName.substring(
382 0, fileName.indexOf(StringPool.QUESTION));
383 }
384
385 return DLAppServiceUtil.getFileEntry(groupId, folderId, fileName);
386 }
387 else {
388 long groupId = GetterUtil.getLong(pathArray[0]);
389
390 String uuid = pathArray[3];
391
392 return DLAppServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);
393 }
394 }
395
396 protected Image getImage(HttpServletRequest request, boolean getDefault)
397 throws PortalException, SystemException {
398
399 Image image = null;
400
401 long imageId = getImageId(request);
402
403 if (imageId > 0) {
404 image = ImageServiceUtil.getImage(imageId);
405
406 String path = GetterUtil.getString(request.getPathInfo());
407
408 if (path.startsWith("/user_female_portrait") ||
409 path.startsWith("/user_male_portrait") ||
410 path.startsWith("/user_portrait")) {
411
412 image = getUserPortraitImageResized(image, imageId);
413 }
414 }
415 else {
416 String uuid = ParamUtil.getString(request, "uuid");
417 long groupId = ParamUtil.getLong(request, "groupId");
418 boolean igSmallImage = ParamUtil.getBoolean(
419 request, "igSmallImage");
420
421 if (Validator.isNotNull(uuid) && (groupId > 0)) {
422 try {
423 FileEntry fileEntry =
424 DLAppServiceUtil.getFileEntryByUuidAndGroupId(
425 uuid, groupId);
426
427 image = convertFileEntry(igSmallImage, fileEntry);
428 }
429 catch (Exception e) {
430 }
431 }
432 }
433
434 if (getDefault) {
435 if (image == null) {
436 if (_log.isWarnEnabled()) {
437 _log.warn("Get a default image for " + imageId);
438 }
439
440 image = getDefaultImage(request, imageId);
441 }
442 }
443
444 return image;
445 }
446
447 protected byte[] getImageBytes(HttpServletRequest request, Image image) {
448 try {
449 if (!PropsValues.IMAGE_AUTO_SCALE) {
450 return image.getTextObj();
451 }
452
453 ImageBag imageBag = null;
454
455 if (image.getImageId() == 0) {
456 imageBag = ImageToolUtil.read(image.getTextObj());
457
458 RenderedImage renderedImage = imageBag.getRenderedImage();
459
460 image.setHeight(renderedImage.getHeight());
461 image.setWidth(renderedImage.getWidth());
462 }
463
464 int height = ParamUtil.getInteger(
465 request, "height", image.getHeight());
466 int width = ParamUtil.getInteger(
467 request, "width", image.getWidth());
468
469 if ((height >= image.getHeight()) && (width >= image.getWidth())) {
470 return image.getTextObj();
471 }
472
473 if (image.getImageId() != 0) {
474 imageBag = ImageToolUtil.read(image.getTextObj());
475 }
476
477 RenderedImage renderedImage = ImageToolUtil.scale(
478 imageBag.getRenderedImage(), height, width);
479
480 return ImageToolUtil.getBytes(renderedImage, imageBag.getType());
481 }
482 catch (Exception e) {
483 if (_log.isWarnEnabled()) {
484 _log.warn("Error scaling image " + image.getImageId(), e);
485 }
486 }
487
488 return image.getTextObj();
489 }
490
491 protected long getImageId(HttpServletRequest request) {
492
493
494
495 long imageId = ParamUtil.getLong(request, "image_id");
496
497 if (imageId <= 0) {
498 imageId = ParamUtil.getLong(request, "img_id");
499 }
500
501 if (imageId <= 0) {
502 imageId = ParamUtil.getLong(request, "i_id");
503 }
504
505 if (imageId <= 0) {
506 long companyId = ParamUtil.getLong(request, "companyId");
507 String screenName = ParamUtil.getString(request, "screenName");
508
509 try {
510 if ((companyId > 0) && Validator.isNotNull(screenName)) {
511 User user = UserLocalServiceUtil.getUserByScreenName(
512 companyId, screenName);
513
514 imageId = user.getPortraitId();
515 }
516 }
517 catch (Exception e) {
518 }
519 }
520
521 return imageId;
522 }
523
524 @Override
525 protected long getLastModified(HttpServletRequest request) {
526 try {
527 Date modifiedDate = null;
528
529 Image image = getImage(request, true);
530
531 if (image != null) {
532 modifiedDate = image.getModifiedDate();
533 }
534 else {
535 String path = HttpUtil.fixPath(request.getPathInfo());
536
537 String[] pathArray = StringUtil.split(path, CharPool.SLASH);
538
539 if (pathArray.length == 0) {
540 return -1;
541 }
542
543 if (pathArray[0].equals("language")) {
544 return -1;
545 }
546
547 FileEntry fileEntry = null;
548
549 try {
550 fileEntry = getFileEntry(pathArray);
551 }
552 catch (Exception e) {
553 }
554
555 if (fileEntry == null) {
556 return -1;
557 }
558 else {
559 String version = ParamUtil.getString(request, "version");
560
561 if (Validator.isNotNull(version)) {
562 FileVersion fileVersion = fileEntry.getFileVersion(
563 version);
564
565 modifiedDate = fileVersion.getModifiedDate();
566 }
567 else {
568 modifiedDate = fileEntry.getModifiedDate();
569 }
570 }
571 }
572
573 if (modifiedDate == null) {
574 modifiedDate = PortalUtil.getUptime();
575 }
576
577
578
579 return (modifiedDate.getTime() / 1000) * 1000;
580 }
581 catch (PrincipalException pe) {
582 if (_log.isWarnEnabled()) {
583 _log.warn(pe, pe);
584 }
585 }
586 catch (Exception e) {
587 _log.error(e, e);
588 }
589
590 return -1;
591 }
592
593 protected Image getUserPortraitImageResized(Image image, long imageId)
594 throws PortalException, SystemException {
595
596 if (image == null) {
597 return null;
598 }
599
600 if (((PropsValues.USERS_IMAGE_MAX_HEIGHT > 0) &&
601 (image.getHeight() > PropsValues.USERS_IMAGE_MAX_HEIGHT)) ||
602 ((PropsValues.USERS_IMAGE_MAX_WIDTH > 0) &&
603 (image.getWidth() > PropsValues.USERS_IMAGE_MAX_WIDTH))) {
604
605 User user = UserLocalServiceUtil.getUserByPortraitId(imageId);
606
607 UserLocalServiceUtil.updatePortrait(
608 user.getUserId(), image.getTextObj());
609
610 return ImageLocalServiceUtil.getImage(imageId);
611 }
612
613 return image;
614 }
615
616 protected boolean isLegacyImageGalleryImageId(
617 HttpServletRequest request, HttpServletResponse response) {
618
619 try {
620 long imageId = getImageId(request);
621
622 if (imageId == 0) {
623 return false;
624 }
625
626 DLFileEntry dlFileEntry =
627 DLFileEntryServiceUtil.fetchFileEntryByImageId(imageId);
628
629 if (dlFileEntry == null) {
630 return false;
631 }
632
633 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
634 WebKeys.THEME_DISPLAY);
635
636 String queryString = StringPool.BLANK;
637
638 if (imageId == dlFileEntry.getSmallImageId()) {
639 queryString = "&imageThumbnail=1";
640 }
641 else if (imageId == dlFileEntry.getSmallImageId()) {
642 queryString = "&imageThumbnail=2";
643 }
644 else if (imageId == dlFileEntry.getSmallImageId()) {
645 queryString = "&imageThumbnail=3";
646 }
647
648 String url = DLUtil.getPreviewURL(
649 new LiferayFileEntry(dlFileEntry),
650 new LiferayFileVersion(dlFileEntry.getFileVersion()),
651 themeDisplay, queryString);
652
653 response.setHeader(HttpHeaders.LOCATION, url);
654 response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
655
656 return true;
657 }
658 catch (Exception e) {
659 }
660
661 return false;
662 }
663
664 protected boolean isSupportsRangeHeader(String contentType) {
665 return _acceptRangesMimeTypes.contains(contentType);
666 }
667
668 protected void processPrincipalException(
669 Throwable t, User user, HttpServletRequest request,
670 HttpServletResponse response)
671 throws IOException, ServletException {
672
673 if (!user.isDefaultUser()) {
674 PortalUtil.sendError(
675 HttpServletResponse.SC_UNAUTHORIZED, (Exception)t, request,
676 response);
677
678 return;
679 }
680
681 String redirect =
682 request.getContextPath() + Portal.PATH_MAIN + "/portal/login";
683
684 String currentURL = PortalUtil.getCurrentURL(request);
685
686 redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);
687
688 response.sendRedirect(redirect);
689 }
690
691 protected void sendDDMRecordFile(
692 HttpServletRequest request, HttpServletResponse response,
693 String[] pathArray)
694 throws Exception {
695
696 if (pathArray.length == 4) {
697 String className = GetterUtil.getString(pathArray[1]);
698 long classPK = GetterUtil.getLong(pathArray[2]);
699 String fieldName = GetterUtil.getString(pathArray[3]);
700
701 Field field = null;
702
703 if (className.equals(DDLRecord.class.getName())) {
704 DDLRecord ddlRecord = DDLRecordLocalServiceUtil.getRecord(
705 classPK);
706
707 field = ddlRecord.getField(fieldName);
708 }
709 else if (className.equals(DLFileEntryMetadata.class.getName())) {
710 DLFileEntryMetadata fileEntryMetadata =
711 DLFileEntryMetadataLocalServiceUtil.getDLFileEntryMetadata(
712 classPK);
713
714 Fields fields = StorageEngineUtil.getFields(
715 fileEntryMetadata.getDDMStorageId());
716
717 field = fields.get(fieldName);
718 }
719
720 DDMUtil.sendFieldFile(request, response, field);
721 }
722 }
723
724 protected void sendDocumentLibrary(
725 HttpServletRequest request, HttpServletResponse response, User user,
726 String path, String[] pathArray)
727 throws Exception {
728
729 if (!PropsValues.WEB_SERVER_SERVLET_DIRECTORY_INDEXING_ENABLED) {
730 response.setStatus(HttpServletResponse.SC_FORBIDDEN);
731
732 return;
733 }
734
735 long groupId = _getGroupId(user.getCompanyId(), pathArray[0]);
736 long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
737
738 for (int i = 1; i < pathArray.length; i++) {
739 String name = pathArray[i];
740
741 try {
742 Folder folder = DLAppServiceUtil.getFolder(
743 groupId, folderId, name);
744
745 folderId = folder.getFolderId();
746 }
747 catch (NoSuchFolderException nsfe) {
748 if (i != (pathArray.length - 1)) {
749 throw nsfe;
750 }
751
752 String title = name;
753
754 sendFile(response, user, groupId, folderId, title);
755
756 return;
757 }
758 }
759
760 try {
761 sendFile(response, user, groupId, folderId, "index.html");
762
763 return;
764 }
765 catch (Exception e) {
766 if ((e instanceof NoSuchFileEntryException) ||
767 (e instanceof PrincipalException)) {
768
769 try {
770 sendFile(response, user, groupId, folderId, "index.htm");
771
772 return;
773 }
774 catch (NoSuchFileEntryException nsfee) {
775 }
776 catch (PrincipalException pe) {
777 }
778 }
779 else {
780 throw e;
781 }
782 }
783
784 List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
785
786 webServerEntries.add(new WebServerEntry(path, "../"));
787
788 List<Folder> folders = DLAppServiceUtil.getFolders(groupId, folderId);
789
790 for (Folder folder : folders) {
791 WebServerEntry webServerEntry = new WebServerEntry(
792 path, folder.getName() + StringPool.SLASH,
793 folder.getCreateDate(), folder.getModifiedDate(),
794 folder.getDescription(), 0);
795
796 webServerEntries.add(webServerEntry);
797 }
798
799 List<FileEntry> fileEntries = DLAppServiceUtil.getFileEntries(
800 groupId, folderId);
801
802 for (FileEntry fileEntry : fileEntries) {
803 WebServerEntry webServerEntry = new WebServerEntry(
804 path, fileEntry.getTitle(), fileEntry.getCreateDate(),
805 fileEntry.getModifiedDate(), fileEntry.getDescription(),
806 fileEntry.getSize());
807
808 webServerEntries.add(webServerEntry);
809 }
810
811 sendHTML(response, path, webServerEntries);
812 }
813
814 protected void sendFile(
815 HttpServletRequest request, HttpServletResponse response, User user,
816 String[] pathArray)
817 throws Exception {
818
819
820
821 FileEntry fileEntry = getFileEntry(pathArray);
822
823 if (fileEntry == null) {
824 throw new NoSuchFileEntryException();
825 }
826
827 String version = ParamUtil.getString(request, "version");
828
829 if (Validator.isNull(version)) {
830 if (Validator.isNotNull(fileEntry.getVersion())) {
831 version = fileEntry.getVersion();
832 }
833 }
834
835 String tempFileId = DLUtil.getTempFileId(
836 fileEntry.getFileEntryId(), version);
837
838 FileVersion fileVersion = fileEntry.getFileVersion(version);
839
840 if (fileVersion.getModel() instanceof DLFileVersion) {
841 LiferayFileVersion liferayFileVersion =
842 (LiferayFileVersion)fileVersion;
843
844 if (liferayFileVersion.isInTrash() ||
845 liferayFileVersion.isInTrashFolder()) {
846
847 int status = ParamUtil.getInteger(
848 request, "status", WorkflowConstants.STATUS_APPROVED);
849
850 if (status != WorkflowConstants.STATUS_IN_TRASH) {
851 throw new NoSuchFileEntryException();
852 }
853
854 PermissionChecker permissionChecker =
855 PermissionThreadLocal.getPermissionChecker();
856
857 if (!permissionChecker.hasPermission(
858 fileEntry.getGroupId(), PortletKeys.TRASH,
859 PortletKeys.TRASH,
860 ActionKeys.ACCESS_IN_CONTROL_PANEL)) {
861
862 throw new PrincipalException();
863 }
864 }
865 }
866
867 if ((ParamUtil.getInteger(request, "height") > 0) ||
868 (ParamUtil.getInteger(request, "width") > 0)) {
869
870 InputStream inputStream = fileVersion.getContentStream(true);
871
872 Image image = ImageLocalServiceUtil.getImage(inputStream);
873
874 writeImage(image, request, response);
875
876 return;
877 }
878
879 String fileName = fileVersion.getTitle();
880
881 String extension = fileVersion.getExtension();
882
883 if (Validator.isNotNull(extension) &&
884 !fileName.endsWith(StringPool.PERIOD + extension)) {
885
886 fileName += StringPool.PERIOD + extension;
887 }
888
889
890
891 boolean converted = false;
892
893 String targetExtension = ParamUtil.getString(
894 request, "targetExtension");
895 int imageThumbnail = ParamUtil.getInteger(request, "imageThumbnail");
896 int documentThumbnail = ParamUtil.getInteger(
897 request, "documentThumbnail");
898 int previewFileIndex = ParamUtil.getInteger(
899 request, "previewFileIndex");
900 boolean audioPreview = ParamUtil.getBoolean(request, "audioPreview");
901 boolean imagePreview = ParamUtil.getBoolean(request, "imagePreview");
902 boolean videoPreview = ParamUtil.getBoolean(request, "videoPreview");
903 int videoThumbnail = ParamUtil.getInteger(request, "videoThumbnail");
904
905 InputStream inputStream = null;
906 long contentLength = 0;
907
908 if ((imageThumbnail > 0) && (imageThumbnail <= 3)) {
909 fileName = FileUtil.stripExtension(fileName).concat(
910 StringPool.PERIOD).concat(
911 ImageProcessorUtil.getThumbnailType(fileVersion));
912
913 int thumbnailIndex = imageThumbnail - 1;
914
915 inputStream = ImageProcessorUtil.getThumbnailAsStream(
916 fileVersion, thumbnailIndex);
917 contentLength = ImageProcessorUtil.getThumbnailFileSize(
918 fileVersion, thumbnailIndex);
919
920 converted = true;
921 }
922 else if ((documentThumbnail > 0) && (documentThumbnail <= 3)) {
923 fileName = FileUtil.stripExtension(fileName).concat(
924 StringPool.PERIOD).concat(PDFProcessor.THUMBNAIL_TYPE);
925
926 int thumbnailIndex = documentThumbnail - 1;
927
928 inputStream = PDFProcessorUtil.getThumbnailAsStream(
929 fileVersion, thumbnailIndex);
930 contentLength = PDFProcessorUtil.getThumbnailFileSize(
931 fileVersion, thumbnailIndex);
932
933 converted = true;
934 }
935 else if (previewFileIndex > 0) {
936 fileName = FileUtil.stripExtension(fileName).concat(
937 StringPool.PERIOD).concat(PDFProcessor.PREVIEW_TYPE);
938 inputStream = PDFProcessorUtil.getPreviewAsStream(
939 fileVersion, previewFileIndex);
940 contentLength = PDFProcessorUtil.getPreviewFileSize(
941 fileVersion, previewFileIndex);
942
943 converted = true;
944 }
945 else if (audioPreview || videoPreview) {
946 String type = ParamUtil.getString(request, "type");
947
948 fileName = FileUtil.stripExtension(fileName).concat(
949 StringPool.PERIOD).concat(type);
950
951 if (audioPreview) {
952 inputStream = AudioProcessorUtil.getPreviewAsStream(
953 fileVersion, type);
954 contentLength = AudioProcessorUtil.getPreviewFileSize(
955 fileVersion, type);
956 }
957 else {
958 inputStream = VideoProcessorUtil.getPreviewAsStream(
959 fileVersion, type);
960 contentLength = VideoProcessorUtil.getPreviewFileSize(
961 fileVersion, type);
962 }
963
964 converted = true;
965 }
966 else if (imagePreview) {
967 String type = ImageProcessorUtil.getPreviewType(fileVersion);
968
969 fileName = FileUtil.stripExtension(fileName).concat(
970 StringPool.PERIOD).concat(type);
971
972 inputStream = ImageProcessorUtil.getPreviewAsStream(fileVersion);
973
974 contentLength = ImageProcessorUtil.getPreviewFileSize(fileVersion);
975
976 converted = true;
977 }
978 else if ((videoThumbnail > 0) && (videoThumbnail <= 3)) {
979 fileName = FileUtil.stripExtension(fileName).concat(
980 StringPool.PERIOD).concat(VideoProcessor.THUMBNAIL_TYPE);
981
982 int thumbnailIndex = videoThumbnail - 1;
983
984 inputStream = VideoProcessorUtil.getThumbnailAsStream(
985 fileVersion, thumbnailIndex);
986 contentLength = VideoProcessorUtil.getThumbnailFileSize(
987 fileVersion, thumbnailIndex);
988
989 converted = true;
990 }
991 else {
992 inputStream = fileVersion.getContentStream(true);
993 contentLength = fileVersion.getSize();
994
995 if (Validator.isNotNull(targetExtension)) {
996 File convertedFile = DocumentConversionUtil.convert(
997 tempFileId, inputStream, extension, targetExtension);
998
999 if (convertedFile != null) {
1000 fileName = FileUtil.stripExtension(fileName).concat(
1001 StringPool.PERIOD).concat(targetExtension);
1002 inputStream = new FileInputStream(convertedFile);
1003 contentLength = convertedFile.length();
1004
1005 converted = true;
1006 }
1007 }
1008 }
1009
1010
1011
1012 String contentType = null;
1013
1014 if (converted) {
1015 contentType = MimeTypesUtil.getContentType(fileName);
1016 }
1017 else {
1018 contentType = fileVersion.getMimeType();
1019 }
1020
1021 if (_log.isDebugEnabled()) {
1022 _log.debug("Content type set to " + contentType);
1023 }
1024
1025
1026
1027 if (isSupportsRangeHeader(contentType)) {
1028 sendFileWithRangeHeader(
1029 request, response, fileName, inputStream, contentLength,
1030 contentType);
1031 }
1032 else {
1033 ServletResponseUtil.sendFile(
1034 request, response, fileName, inputStream, contentLength,
1035 contentType);
1036 }
1037 }
1038
1039 protected void sendFile(
1040 HttpServletResponse response, User user, long groupId,
1041 long folderId, String title)
1042 throws Exception {
1043
1044 FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
1045 groupId, folderId, title);
1046
1047 String contentType = fileEntry.getMimeType();
1048
1049 response.setContentType(contentType);
1050
1051 InputStream inputStream = fileEntry.getContentStream();
1052
1053 ServletResponseUtil.write(response, inputStream, fileEntry.getSize());
1054 }
1055
1056 protected void sendFileWithRangeHeader(
1057 HttpServletRequest request, HttpServletResponse response,
1058 String fileName, InputStream inputStream, long contentLength,
1059 String contentType)
1060 throws IOException {
1061
1062 if (_log.isDebugEnabled()) {
1063 _log.debug("Accepting ranges for the file " + fileName);
1064 }
1065
1066 response.setHeader(
1067 HttpHeaders.ACCEPT_RANGES, HttpHeaders.ACCEPT_RANGES_BYTES_VALUE);
1068
1069 List<Range> ranges = null;
1070
1071 try {
1072 ranges = ServletResponseUtil.getRanges(
1073 request, response, contentLength);
1074 }
1075 catch (IOException ioe) {
1076 if (_log.isErrorEnabled()) {
1077 _log.error(ioe);
1078 }
1079
1080 response.setHeader(
1081 HttpHeaders.CONTENT_RANGE, "bytes */" + contentLength);
1082
1083 response.sendError(
1084 HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
1085
1086 return;
1087 }
1088
1089 if ((ranges == null) || ranges.isEmpty()) {
1090 ServletResponseUtil.sendFile(
1091 request, response, fileName, inputStream, contentLength,
1092 contentType);
1093 }
1094 else {
1095 if (_log.isDebugEnabled()) {
1096 _log.debug(
1097 "Request has range header " +
1098 request.getHeader(HttpHeaders.RANGE));
1099 }
1100
1101 ServletResponseUtil.write(
1102 request, response, fileName, ranges, inputStream, contentLength,
1103 contentType);
1104 }
1105 }
1106
1107 protected void sendGroups(
1108 HttpServletResponse response, User user, String path)
1109 throws Exception {
1110
1111 if (!PropsValues.WEB_SERVER_SERVLET_DIRECTORY_INDEXING_ENABLED) {
1112 response.setStatus(HttpServletResponse.SC_FORBIDDEN);
1113
1114 return;
1115 }
1116
1117 List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
1118
1119 List<Group> groups = WebDAVUtil.getGroups(user);
1120
1121 for (Group group : groups) {
1122 String name = HttpUtil.fixPath(group.getFriendlyURL());
1123
1124 WebServerEntry webServerEntry = new WebServerEntry(
1125 path, name + StringPool.SLASH, null, null,
1126 group.getDescription(), 0);
1127
1128 webServerEntries.add(webServerEntry);
1129 }
1130
1131 sendHTML(response, path, webServerEntries);
1132 }
1133
1134 protected void sendHTML(
1135 HttpServletResponse response, String path,
1136 List<WebServerEntry> webServerEntries)
1137 throws Exception {
1138
1139 Template template = TemplateManagerUtil.getTemplate(
1140 TemplateManager.FREEMARKER, _templateResource,
1141 TemplateContextType.RESTRICTED);
1142
1143 template.put("dateFormat", _dateFormat);
1144 template.put("entries", webServerEntries);
1145 template.put("path", HttpUtil.encodePath(path));
1146
1147 if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT) {
1148 }
1149 else if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL) {
1150 template.put("releaseInfo", ReleaseInfo.getName());
1151 }
1152 else {
1153 template.put("releaseInfo", ReleaseInfo.getReleaseInfo());
1154 }
1155
1156 template.put("validator", Validator_IW.getInstance());
1157
1158 response.setContentType(ContentTypes.TEXT_HTML_UTF8);
1159
1160 template.processTemplate(response.getWriter());
1161 }
1162
1163 protected void writeImage(
1164 Image image, HttpServletRequest request, HttpServletResponse response) {
1165
1166 if (image == null) {
1167 return;
1168 }
1169
1170 String contentType = null;
1171
1172 String type = image.getType();
1173
1174 if (!type.equals(ImageConstants.TYPE_NOT_AVAILABLE)) {
1175 contentType = MimeTypesUtil.getContentType("A." + type);
1176
1177 response.setContentType(contentType);
1178 }
1179
1180 String fileName = ParamUtil.getString(request, "fileName");
1181
1182 try {
1183 byte[] bytes = getImageBytes(request, image);
1184
1185 if (Validator.isNotNull(fileName)) {
1186 ServletResponseUtil.sendFile(
1187 request, response, fileName, bytes, contentType);
1188 }
1189 else {
1190 ServletResponseUtil.write(response, bytes);
1191 }
1192 }
1193 catch (Exception e) {
1194 if (_log.isWarnEnabled()) {
1195 _log.warn(e, e);
1196 }
1197 }
1198 }
1199
1200 private static void _checkDDMRecord(String[] pathArray) throws Exception {
1201 if (pathArray.length == 3) {
1202 String className = GetterUtil.getString(pathArray[1]);
1203 long classPK = GetterUtil.getLong(pathArray[2]);
1204
1205 if (className.equals(DDLRecord.class.getName())) {
1206 DDLRecordLocalServiceUtil.getRecord(classPK);
1207 }
1208 else if (className.equals(DLFileEntryMetadata.class.getName())) {
1209 DLFileEntryMetadataLocalServiceUtil.getDLFileEntryMetadata(
1210 classPK);
1211 }
1212 }
1213 }
1214
1215 private static void _checkFileEntry(String[] pathArray) throws Exception {
1216 if (pathArray.length == 1) {
1217 long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);
1218
1219 DLFileShortcut dlFileShortcut =
1220 DLAppLocalServiceUtil.getFileShortcut(dlFileShortcutId);
1221
1222 DLAppLocalServiceUtil.getFileEntry(
1223 dlFileShortcut.getToFileEntryId());
1224 }
1225 else if (pathArray.length == 2) {
1226
1227
1228
1229 }
1230 else if (pathArray.length == 3) {
1231 long groupId = GetterUtil.getLong(pathArray[0]);
1232 long folderId = GetterUtil.getLong(pathArray[1]);
1233 String fileName = HttpUtil.decodeURL(pathArray[2]);
1234
1235 try {
1236 DLAppLocalServiceUtil.getFileEntry(groupId, folderId, fileName);
1237 }
1238 catch (RepositoryException re) {
1239 }
1240 }
1241 else {
1242 long groupId = GetterUtil.getLong(pathArray[0]);
1243
1244 String uuid = pathArray[3];
1245
1246 try {
1247 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1248 uuid, groupId);
1249 }
1250 catch (RepositoryException re) {
1251 }
1252 }
1253 }
1254
1255 private static long _getGroupId(long companyId, String name)
1256 throws Exception {
1257
1258 try {
1259 Group group = GroupLocalServiceUtil.getFriendlyURLGroup(
1260 companyId, StringPool.SLASH + name);
1261
1262 return group.getGroupId();
1263 }
1264 catch (NoSuchGroupException nsge) {
1265 }
1266
1267 User user = UserLocalServiceUtil.getUserByScreenName(companyId, name);
1268
1269 Group group = user.getGroup();
1270
1271 return group.getGroupId();
1272 }
1273
1274 private static User _getUser(HttpServletRequest request) throws Exception {
1275 HttpSession session = request.getSession();
1276
1277 if (PortalSessionThreadLocal.getHttpSession() == null) {
1278 PortalSessionThreadLocal.setHttpSession(session);
1279 }
1280
1281 User user = PortalUtil.getUser(request);
1282
1283 if (user != null) {
1284 return user;
1285 }
1286
1287 String userIdString = (String)session.getAttribute("j_username");
1288 String password = (String)session.getAttribute("j_password");
1289
1290 if ((userIdString != null) && (password != null)) {
1291 long userId = GetterUtil.getLong(userIdString);
1292
1293 user = UserLocalServiceUtil.getUser(userId);
1294 }
1295 else {
1296 long companyId = PortalUtil.getCompanyId(request);
1297
1298 Company company = CompanyLocalServiceUtil.getCompany(companyId);
1299
1300 user = company.getDefaultUser();
1301 }
1302
1303 return user;
1304 }
1305
1306 private static final String _DATE_FORMAT_PATTERN = "d MMM yyyy HH:mm z";
1307
1308 private static final String _PATH_DDM = "ddm";
1309
1310 private static final boolean _WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT =
1311 PropsValues.WEB_SERVER_SERVLET_VERSION_VERBOSITY.equalsIgnoreCase(
1312 ReleaseInfo.getName());
1313
1314 private static final boolean _WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL =
1315 PropsValues.WEB_SERVER_SERVLET_VERSION_VERBOSITY.equalsIgnoreCase(
1316 "partial");
1317
1318 private static Log _log = LogFactoryUtil.getLog(WebServerServlet.class);
1319
1320 private static Set<String> _acceptRangesMimeTypes = SetUtil.fromArray(
1321 PropsValues.WEB_SERVER_SERVLET_ACCEPT_RANGES_MIME_TYPES);
1322
1323 private static Format _dateFormat =
1324 FastDateFormatFactoryUtil.getSimpleDateFormat(_DATE_FORMAT_PATTERN);
1325
1326 private boolean _lastModified = true;
1327 private TemplateResource _templateResource;
1328
1329 }