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