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