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