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