ReportingServicesProxyServlet.java 6.28 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.ServletException
 *  javax.servlet.ServletOutputStream
 *  org.apache.commons.io.IOUtils
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.sling.SlingServlet
 *  org.apache.http.HttpEntity
 *  org.apache.http.HttpResponse
 *  org.apache.http.StatusLine
 *  org.apache.http.client.HttpClient
 *  org.apache.http.client.methods.CloseableHttpResponse
 *  org.apache.http.client.methods.HttpGet
 *  org.apache.http.client.methods.HttpUriRequest
 *  org.apache.http.client.utils.HttpClientUtils
 *  org.apache.http.client.utils.URIBuilder
 *  org.apache.http.impl.client.CloseableHttpClient
 *  org.apache.http.impl.client.HttpClientBuilder
 *  org.apache.http.osgi.services.HttpClientBuilderFactory
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.servlets.SlingSafeMethodsServlet
 *  org.apache.sling.commons.osgi.PropertiesUtil
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.contentinsight.impl.servlets;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Dictionary;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.osgi.services.HttpClientBuilderFactory;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingServlet(generateComponent=1, metatype=1, resourceTypes={"cq/contentinsight/proxy"}, extensions={"json"}, selectors={"reportingservices"}, methods={"GET"}, label="Reporting Services API proxy servlet", description="Proxy servlet for Reporting Services API")
public class ReportingServicesProxyServlet
extends SlingSafeMethodsServlet {
    private static final String DEFAULT_API_OMNITURE_URL = ".*/api[0-9]*.omniture.com/.*";
    @Property(name="reportingservices.proxy.whitelist", label="Whitelist", description="Allowed destinations for the reporting services proxy servlet", cardinality=Integer.MAX_VALUE, value={".*/api[0-9]*.omniture.com/.*"})
    private String[] whiteList = new String[]{".*/api[0-9]*.omniture.com/.*"};
    @Reference
    private HttpClientBuilderFactory clientBuilderFactory;
    private static final long serialVersionUID = 7044811756109092040L;
    private static final Logger LOG = LoggerFactory.getLogger(ReportingServicesProxyServlet.class);

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        String url = request.getParameter("url");
        String query = request.getParameter("q");
        if (url == null || query == null) {
            response.setStatus(400);
            return;
        }
        if (!this.isUrlAllowed(url)) {
            LOG.warn("Received url " + url + " not whitelisted!");
            return;
        }
        CloseableHttpClient httpClient = this.clientBuilderFactory.newBuilder().build();
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            uriBuilder.addParameter("q", query);
            HttpGet get = new HttpGet(uriBuilder.build());
            get.setHeader("x-adobe-rs-auth", request.getHeader("x-adobe-rs-auth"));
            CloseableHttpResponse getResponse = null;
            try {
                getResponse = httpClient.execute((HttpUriRequest)get);
                int status = getResponse.getStatusLine().getStatusCode();
                IOUtils.copy((InputStream)getResponse.getEntity().getContent(), (OutputStream)response.getOutputStream());
                response.setStatus(status);
            }
            finally {
                HttpClientUtils.closeQuietly((HttpResponse)getResponse);
            }
        }
        catch (URISyntaxException e) {
            LOG.error("Invalid URL: " + url, (Throwable)e);
        }
        finally {
            HttpClientUtils.closeQuietly((HttpClient)httpClient);
        }
    }

    private boolean isUrlAllowed(String url) {
        Pattern pattern;
        String whitelistedRegex;
        boolean isAllowed = false;
        String[] arrstring = this.whiteList;
        int n = arrstring.length;
        for (int i = 0; i < n && !(isAllowed = (pattern = Pattern.compile(whitelistedRegex = arrstring[i])).matcher(url).matches()); ++i) {
        }
        return isAllowed;
    }

    @Activate
    protected void activate(ComponentContext ctx) {
        this.whiteList = PropertiesUtil.toStringArray(ctx.getProperties().get("reportingservices.proxy.whitelist"), (String[])new String[]{".*/api[0-9]*.omniture.com/.*"});
    }

    protected void bindClientBuilderFactory(HttpClientBuilderFactory httpClientBuilderFactory) {
        this.clientBuilderFactory = httpClientBuilderFactory;
    }

    protected void unbindClientBuilderFactory(HttpClientBuilderFactory httpClientBuilderFactory) {
        if (this.clientBuilderFactory == httpClientBuilderFactory) {
            this.clientBuilderFactory = null;
        }
    }
}