ClientLibraryProxyServlet.java 13.5 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.servlet.ServletContext
 *  javax.servlet.ServletException
 *  javax.servlet.ServletOutputStream
 *  javax.servlet.http.HttpServletRequest
 *  org.apache.commons.io.IOUtils
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.sling.SlingServlet
 *  org.apache.jackrabbit.util.Text
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceMetadata
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.apache.sling.api.servlets.SlingSafeMethodsServlet
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.apache.sling.jcr.resource.JcrResourceResolverFactory
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.ui.clientlibs.impl;

import com.adobe.granite.ui.clientlibs.HtmlLibrary;
import com.adobe.granite.ui.clientlibs.HtmlLibraryManager;
import com.adobe.granite.ui.clientlibs.LibraryType;
import com.adobe.granite.ui.clientlibs.impl.HtmlLibraryImpl;
import com.adobe.granite.ui.clientlibs.impl.HtmlLibraryManagerImpl;
import com.adobe.granite.ui.clientlibs.impl.HtmlLibraryServlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingServlet(paths={"/libs/sling/servlet/default/clientlibs.GET.servlet"})
public class ClientLibraryProxyServlet
extends SlingSafeMethodsServlet {
    private static final Logger log = LoggerFactory.getLogger(ClientLibraryProxyServlet.class);
    @Reference
    private HtmlLibraryManager hMgr = null;
    @Reference
    SlingRepository repository = null;
    @Reference
    JcrResourceResolverFactory resolverFactory = null;
    private final long maxAge = 86400;

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        block47 : {
            Resource r = request.getResource();
            String[] selectors = request.getRequestPathInfo().getSelectors();
            String suffix = request.getRequestPathInfo().getSuffix();
            if (selectors.length != 0 || !"/etc".equals(r.getPath()) || ResourceUtil.isNonExistingResource((Resource)r) || suffix == null || suffix.length() < 2) {
                log.info("Proxy request to {} not supported.", (Object)request.getRequestURI());
                response.setStatus(404);
                response.flushBuffer();
                return;
            }
            String relPath = suffix.substring(1);
            HtmlLibraryManagerImpl mgr = (HtmlLibraryManagerImpl)this.hMgr;
            ResourceResolver resolver = request.getResourceResolver();
            String[] sp = resolver.getSearchPath();
            Session session = null;
            try {
                Resource staticResource = ClientLibraryProxyServlet.resolve(resolver, sp, relPath);
                if (staticResource == null) {
                    session = mgr.getServiceSession();
                    ResourceResolver sessionResolver = this.resolverFactory.getResourceResolver(session);
                    staticResource = ClientLibraryProxyServlet.resolve(sessionResolver, sp, relPath);
                }
                if (staticResource == null) {
                    String s;
                    int idxLastSlash = relPath.lastIndexOf(47);
                    int lastDot = relPath.lastIndexOf(46);
                    if (lastDot < idxLastSlash) {
                        log.info("Unable to proxy {}. No extension", (Object)relPath);
                        response.setStatus(404);
                        response.flushBuffer();
                        return;
                    }
                    String ext = relPath.substring(lastDot);
                    LibraryType type = null;
                    if (ext.equals(LibraryType.JS.extension)) {
                        type = LibraryType.JS;
                    } else if (ext.equals(LibraryType.CSS.extension)) {
                        type = LibraryType.CSS;
                    }
                    if (type == null) {
                        log.info("Unable to proxy {}. No supported type for {}", (Object)suffix, (Object)ext);
                        response.setStatus(404);
                        response.flushBuffer();
                        return;
                    }
                    int firstDot = relPath.indexOf(46, idxLastSlash);
                    String libRelPath = relPath.substring(0, firstDot);
                    HtmlLibrary lib = null;
                    String[] arr$ = sp;
                    int len$ = arr$.length;
                    for (int i$ = 0; i$ < len$ && (lib = mgr.getLibrary(type, (s = arr$[i$]) + libRelPath, true)) == null; ++i$) {
                    }
                    if (lib == null) {
                        log.info("Unable to proxy {}. No such library for {}", (Object)relPath, (Object)libRelPath);
                        response.setStatus(404);
                        response.flushBuffer();
                        return;
                    }
                    Boolean allowed = mgr.proxyAllowed(lib.getLibraryPath(), null);
                    if (allowed == null || !allowed.booleanValue()) {
                        log.info("Unable to proxy library at {}. Not allowed.", (Object)lib.getPath());
                        response.setStatus(404);
                        response.flushBuffer();
                        return;
                    }
                    if (HtmlLibraryServlet.isDebug(request)) {
                        log.debug("Creating {} debug library for {}", (Object)lib.getType(), (Object)lib.getLibraryPath());
                        try {
                            if (lib.getType() == LibraryType.JS) {
                                HtmlLibraryServlet.createJsDebugScript(lib, request, response, mgr.isDebugEnabled());
                            } else {
                                HtmlLibraryServlet.createCssDebugScript(lib, request, response, mgr.isDebugEnabled());
                            }
                            log.debug("Created {} debug library for {}", (Object)lib.getType(), (Object)lib.getLibraryPath());
                        }
                        catch (Exception e) {
                            log.error("Cannot create library for {}", (Object)request.getRequestURI(), (Object)e);
                            response.sendError(404);
                        }
                    } else {
                        boolean minified = false;
                        if (firstDot < lastDot) {
                            String selectorString = relPath.substring(firstDot + 1, lastDot);
                            String[] suffixSelectors = Text.explode((String)selectorString, (int)46);
                            minified = "min".equals(suffixSelectors[0]);
                        }
                        mgr.send((HtmlLibraryImpl)lib, request, response, minified);
                    }
                    break block47;
                }
                String libPath = Text.getRelativeParent((String)relPath, (int)1);
                boolean isBelowResources = "resources".equals(Text.getName((String)libPath));
                Boolean allowed = null;
                while (allowed == null && libPath.length() > 0) {
                    allowed = mgr.proxyAllowed(libPath, sp);
                    if (allowed != null || !"resources".equals(Text.getName((String)(libPath = Text.getRelativeParent((String)libPath, (int)1))))) continue;
                    isBelowResources = true;
                }
                if (allowed == null) {
                    log.info("Unable to proxy static resources at {}. No below valid library.", (Object)relPath);
                    response.setStatus(404);
                    response.flushBuffer();
                    return;
                }
                if (!allowed.booleanValue()) {
                    log.info("Unable to proxy static resources at {}. Proxy disabled by library.", (Object)relPath);
                    response.setStatus(404);
                    response.flushBuffer();
                    return;
                }
                if (!isBelowResources && !mgr.isDebugEnabled()) {
                    log.info("Unable to proxy static resources at {}. Not allowed outside resources.", (Object)relPath);
                    response.setStatus(404);
                    response.flushBuffer();
                    return;
                }
                ResourceMetadata meta = staticResource.getResourceMetadata();
                long modifTime = meta.getModificationTime();
                if (this.unmodified((HttpServletRequest)request, modifTime)) {
                    response.setHeader("Cache-Control", "max-age=86400, public");
                    response.setStatus(304);
                    return;
                }
                InputStream is = (InputStream)staticResource.adaptTo(InputStream.class);
                if (is == null) {
                    log.info("Resource at {} is no streamable", (Object)staticResource.getPath());
                    response.setStatus(404);
                    response.flushBuffer();
                    return;
                }
                try {
                    String encoding;
                    String ct;
                    String contentType;
                    long length = meta.getContentLength();
                    if (length >= 0) {
                        response.setHeader("Content-Length", String.valueOf(length));
                    }
                    response.setHeader("Cache-Control", "max-age=86400, public");
                    if (modifTime > 0) {
                        response.setDateHeader("Last-Modified", modifTime);
                    }
                    if (((contentType = meta.getContentType()) == null || "application/octet-stream".equals(contentType)) && (ct = this.getServletContext().getMimeType(relPath)) != null) {
                        contentType = ct;
                    }
                    if (contentType != null) {
                        response.setContentType(contentType);
                    }
                    if ((encoding = meta.getCharacterEncoding()) != null) {
                        response.setCharacterEncoding(encoding);
                    }
                    IOUtils.copy((InputStream)is, (OutputStream)response.getOutputStream());
                }
                finally {
                    IOUtils.closeQuietly((InputStream)is);
                }
            }
            catch (RepositoryException e) {
                log.error("Error while accessing repository", (Throwable)e);
                response.setStatus(500);
                response.flushBuffer();
            }
            finally {
                if (session != null) {
                    session.logout();
                }
            }
        }
    }

    private static Resource resolve(ResourceResolver resolver, String[] sp, String relPath) {
        for (String s : sp) {
            Resource r = resolver.getResource(s + relPath);
            if (r == null) continue;
            return r;
        }
        return null;
    }

    private boolean unmodified(HttpServletRequest request, long modifTime) {
        if (modifTime > 0) {
            long modTime = modifTime / 1000;
            long ims = request.getDateHeader("If-Modified-Since") / 1000;
            return modTime <= ims;
        }
        return false;
    }

    protected void bindHMgr(HtmlLibraryManager htmlLibraryManager) {
        this.hMgr = htmlLibraryManager;
    }

    protected void unbindHMgr(HtmlLibraryManager htmlLibraryManager) {
        if (this.hMgr == htmlLibraryManager) {
            this.hMgr = null;
        }
    }

    protected void bindRepository(SlingRepository slingRepository) {
        this.repository = slingRepository;
    }

    protected void unbindRepository(SlingRepository slingRepository) {
        if (this.repository == slingRepository) {
            this.repository = null;
        }
    }

    protected void bindResolverFactory(JcrResourceResolverFactory jcrResourceResolverFactory) {
        this.resolverFactory = jcrResourceResolverFactory;
    }

    protected void unbindResolverFactory(JcrResourceResolverFactory jcrResourceResolverFactory) {
        if (this.resolverFactory == jcrResourceResolverFactory) {
            this.resolverFactory = null;
        }
    }
}