com.subgraph.vega.internal.http.proxy.HttpProxyService.java Source code

Java tutorial

Introduction

Here is the source code for com.subgraph.vega.internal.http.proxy.HttpProxyService.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Subgraph.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Subgraph - initial API and implementation
 ******************************************************************************/
package com.subgraph.vega.internal.http.proxy;

import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.http.client.HttpClient;

import com.subgraph.vega.api.analysis.IContentAnalyzer;
import com.subgraph.vega.api.analysis.IContentAnalyzerFactory;
import com.subgraph.vega.api.http.proxy.IHttpInterceptProxyEventHandler;
import com.subgraph.vega.api.http.proxy.IHttpInterceptor;
import com.subgraph.vega.api.http.proxy.IHttpProxyService;
import com.subgraph.vega.api.http.proxy.IHttpProxyTransactionManipulator;
import com.subgraph.vega.api.http.proxy.IProxyTransaction;
import com.subgraph.vega.api.http.requests.IHttpRequestEngine;
import com.subgraph.vega.api.http.requests.IHttpRequestEngineFactory;
import com.subgraph.vega.api.model.IModel;
import com.subgraph.vega.api.model.IWorkspace;
import com.subgraph.vega.api.paths.IPathFinder;
import com.subgraph.vega.api.scanner.modules.IResponseProcessingModule;
import com.subgraph.vega.api.scanner.modules.IScannerModuleRegistry;
import com.subgraph.vega.internal.http.proxy.ssl.ProxySSLInitializationException;
import com.subgraph.vega.internal.http.proxy.ssl.SSLContextRepository;

public class HttpProxyService implements IHttpProxyService {
    private final Logger logger = Logger.getLogger(HttpProxyService.class.getName());
    private boolean isRunning = false;
    private boolean isPassthrough = false;
    private final IHttpInterceptProxyEventHandler eventHandler;
    private IModel model;
    private IHttpRequestEngineFactory requestEngineFactory;
    private IContentAnalyzerFactory contentAnalyzerFactory;
    private IContentAnalyzer contentAnalyzer;
    private List<IResponseProcessingModule> responseProcessingModules;

    private IScannerModuleRegistry moduleRepository;
    private HttpProxy proxy;
    private IWorkspace currentWorkspace;
    private IPathFinder pathFinder;

    private ProxyTransactionManipulator transactionManipulator;
    private HttpInterceptor interceptor;
    private SSLContextRepository sslContextRepository;

    public HttpProxyService() {
        eventHandler = new IHttpInterceptProxyEventHandler() {
            @Override
            public void handleRequest(IProxyTransaction transaction) {
                processTransaction(transaction);
            }
        };
        transactionManipulator = new ProxyTransactionManipulator();
    }

    public void activate() {
        interceptor = new HttpInterceptor(model);
        responseProcessingModules = loadModules();
        try {
            sslContextRepository = SSLContextRepository.createInstance(pathFinder.getVegaDirectory());
        } catch (ProxySSLInitializationException e) {
            sslContextRepository = null;
            logger.warning("Failed to initialize SSL support in proxy.  SSL interception will be disabled. ("
                    + e.getMessage() + ")");
        }
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }

    @Override
    public boolean isPassthrough() {
        synchronized (this) {
            return isPassthrough;
        }
    }

    @Override
    public void start(int proxyPort) {
        currentWorkspace = model.getCurrentWorkspace();
        if (currentWorkspace == null)
            throw new IllegalStateException("Cannot start proxy because no workspace is currently open");
        currentWorkspace.lock();
        responseProcessingModules = loadModules();
        contentAnalyzer = contentAnalyzerFactory
                .createContentAnalyzer(currentWorkspace.getScanAlertRepository().getProxyScanInstance());
        contentAnalyzer.setResponseProcessingModules(responseProcessingModules);
        contentAnalyzer.setDefaultAddToRequestLog(true);
        contentAnalyzer.setAddLinksToModel(true);

        final HttpClient httpClient = requestEngineFactory.createBasicClient();
        final IHttpRequestEngine requestEngine = requestEngineFactory.createRequestEngine(httpClient,
                requestEngineFactory.createConfig());
        proxy = new HttpProxy(proxyPort, transactionManipulator, interceptor, requestEngine, sslContextRepository);
        proxy.registerEventHandler(eventHandler);
        proxy.startProxy();
    }

    private List<IResponseProcessingModule> loadModules() {
        if (responseProcessingModules == null) {
            return moduleRepository.getResponseProcessingModules();
        } else {
            return moduleRepository.updateResponseProcessingModules(responseProcessingModules);
        }
    }

    private void processTransaction(IProxyTransaction transaction) {
        synchronized (this) {
            if (transaction.getResponse() == null || contentAnalyzer == null || isPassthrough) {
                return;
            }
        }
        try {
            contentAnalyzer.processResponse(transaction.getResponse());
        } catch (RuntimeException e) {
            logger.log(Level.WARNING, "Exception processing transaction response: " + e.getMessage(), e);
        }
    }

    @Override
    public void stop() {
        if (currentWorkspace == null)
            throw new IllegalStateException("No workspace is open");
        isRunning = false;
        proxy.unregisterEventHandler(eventHandler);
        proxy.stopProxy();
        contentAnalyzer = null;
        currentWorkspace.unlock();
    }

    @Override
    public void setPassthrough(boolean enabled) {
        synchronized (this) {
            isPassthrough = enabled;
            interceptor.setEnabled(!enabled);
        }
    }

    @Override
    public int getListenPort() {
        if (isRunning) {
            return proxy.getListenPort();
        }
        return -1;
    }

    @Override
    public IHttpProxyTransactionManipulator getTransactionManipulator() {
        return transactionManipulator;
    }

    @Override
    public IHttpInterceptor getInterceptor() {
        return interceptor;
    }

    protected void setModel(IModel model) {
        this.model = model;
    }

    protected void unsetModel(IModel model) {
        this.model = null;
    }

    protected void setContentAnalyzerFactory(IContentAnalyzerFactory factory) {
        this.contentAnalyzerFactory = factory;
    }

    protected void unsetContentAnalyzerFactory(IContentAnalyzerFactory factory) {
        this.contentAnalyzerFactory = null;
    }

    protected void setRequestEngineFactory(IHttpRequestEngineFactory factory) {
        this.requestEngineFactory = factory;
    }

    protected void unsetRequestEngineFactory(IHttpRequestEngineFactory factory) {
        this.requestEngineFactory = null;
    }

    protected void setModuleRepository(IScannerModuleRegistry moduleRepository) {
        this.moduleRepository = moduleRepository;
    }

    protected void unsetModuleRepository(IScannerModuleRegistry moduleRepository) {
        this.moduleRepository = null;
    }

    protected void setPathFinder(IPathFinder pathFinder) {
        this.pathFinder = pathFinder;
    }

    protected void unsetPathFinder(IPathFinder pathFinder) {
        this.pathFinder = null;
    }

    @Override
    public List<IResponseProcessingModule> getResponseProcessingModules() {
        responseProcessingModules = loadModules();
        if (responseProcessingModules == null) {
            return Collections.emptyList();
        } else {
            return responseProcessingModules;
        }
    }

}