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