All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mike10004.seleniumhelp.TrafficCollector Maven / Gradle / Ivy

There is a newer version: 0.58
Show newest version
package com.github.mike10004.seleniumhelp;

import com.browserup.bup.BrowserUpProxy;
import com.browserup.bup.BrowserUpProxyServer;
import com.browserup.bup.mitm.CertificateAndKeySource;
import org.littleshoot.proxy.HttpFiltersSource;
import org.openqa.selenium.WebDriverException;

import javax.annotation.Nullable;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;

/**
 * Interface of a service that enables collection of HTTP traffic driven by a web-browsing session.
 */
public interface TrafficCollector {

    /**
     * Collects traffic generated by the given generator into a HAR. This invokes
     * {@link #collect(TrafficGenerator, TrafficMonitor)} with a null monitor reference.
     * @param generator the generator
     * @param  type of result the generator returns
     * @return the HAR containing all traffic generated
     * @throws IOException if something I/O related goes awry
     * @throws WebDriverException if the web driver could not be created or the generator throws one
     */
     HarPlus collect(TrafficGenerator generator) throws IOException, WebDriverException;

    /**
     * Collects traffic generated by the given generator into a HAR. Notifications of request/response
     * interactions can be sent to the given monitor, optionally.
     * @param generator the generator
     * @param  type of result the generator returns
     * @param monitor a monitor, or null
     * @return the HAR containing all traffic generated
     * @throws IOException on I/O error
     * @throws WebDriverException if the web driver could not be created or the generator throws one
     */
     HarPlus collect(TrafficGenerator generator, @Nullable TrafficMonitor monitor) throws IOException, WebDriverException;
    /**
     * Monitors traffic generated by the given generator. This like
     * {@link #collect(TrafficGenerator, TrafficMonitor)} but without capturing a HAR.
     * @param generator the traffic generator
     * @param monitor the monitor
     * @param  generator result type
     * @return the generator result
     * @throws IOException on I/O error
     * @throws WebDriverException on webdriver error
     */
     R monitor(TrafficGenerator generator, TrafficMonitor monitor) throws IOException, WebDriverException;

    /**
     * Causes traffic to be generated by the given generator and returns the result.
     * This is essentially {@link #monitor(TrafficGenerator, TrafficMonitor)} without
     * notifying a monitor of request/response interactions.
     * @param generator the traffic generator
     * @param  generator result type
     * @return the generator result
     * @throws IOException on I/O error
     * @throws WebDriverException on webdriver error
     */
     R drive(TrafficGenerator generator) throws IOException, WebDriverException;

    /**
     * Returns a new builder instance.
     * @param webDriverFactory the webdriver factory
     * @return a builder
     */
    static TrafficCollectorImpl.Builder builder(WebDriverFactory webDriverFactory) {
        return new TrafficCollectorImpl.Builder(webDriverFactory);
    }

    /**
     * Builder of traffic collector instances.
     */
    final class Builder {

        private final WebDriverFactory webDriverFactory;
        private CertificateAndKeySource certificateAndKeySource = null;
        private final List httpFiltersSources = new ArrayList<>();
        private BmpConfigurator upstreamConfigurator = BmpConfigurator.noUpstreamProxy();
        private Supplier interceptingProxyInstantiator = BrowserUpProxyServer::new;
        private final List harPostProcessors = new ArrayList<>();
        private ExceptionReactor exceptionReactor = ExceptionReactor.PROPAGATE;

        Builder(WebDriverFactory webDriverFactory) {
            this.webDriverFactory = requireNonNull(webDriverFactory);
            httpFiltersSources.add(AnonymizingFiltersSource.getInstance());
        }

        /**
         * Configures the collector to react to exceptions during collection with the specified service instance.
         * By default, exceptions are re-thrown.
         * @param exceptionReactor the reactor service
         * @return this builder instance
         */
        public Builder onException(ExceptionReactor exceptionReactor) {
            this.exceptionReactor = requireNonNull(exceptionReactor);
            return this;
        }

        /**
         * Configures the collector to collect HTTPS traffic by accepting TLS socket connections
         * using the given trust data.
         * @param certificateAndKeySource the certificate and key source
         * @return this builder instance
         */
        public Builder collectHttps(CertificateAndKeySource certificateAndKeySource) {
            this.certificateAndKeySource = requireNonNull(certificateAndKeySource);
            return this;
        }

        /**
         * Sets the supplier of the proxy server instance that is used to intercept and collect traffic.
         * The default is a supplier of the proxy that uses the default constructor.
         * @param interceptingProxyInstantiator the instantiator
         * @return this builder instance
         */
        public Builder interceptingProxyInstantiator(Supplier interceptingProxyInstantiator) {
            this.interceptingProxyInstantiator = requireNonNull(interceptingProxyInstantiator);
            return this;
        }

        /**
         * Configures the collector not to remove headers that indicate traffic is passing through a proxy.
         * By default, the intercepting proxy does not add/remove/change any headers, and this negates that
         * behavior.
         * @return this builder instance
         */
        public Builder nonAnonymizing() {
            httpFiltersSources.remove(AnonymizingFiltersSource.getInstance());
            return this;
        }

        /**
         * Adds a filter source to the list of filter sources.
         * @param filter a filter source
         * @return this builder instance
         */
        public Builder filter(HttpFiltersSource filter) {
            httpFiltersSources.add(filter);
            return this;
        }

        /**
         * Adds all argument filters sources to this builder's filters list.
         * @param val the filters sources to add
         * @return this builder instance
         */
        public Builder filters(Collection val) {
            httpFiltersSources.addAll(val);
            return this;
        }

        /**
         * Configures the collector instance not to use an upstream proxy.
         * This is the default.
         * @return this builder instance
         */
        public Builder noUpstreamProxy() {
            return upstreamProxy(BmpConfigurator.noUpstreamProxy());
        }

        private Builder upstreamProxy(BmpConfigurator configurator) {
            this.upstreamConfigurator = requireNonNull(configurator);
            return this;
        }

        /**
         * @deprecated use {@link #upstreamProxy(UpstreamProxyDefinition)}
         * @see UriProxySpecification#toUpstreamProxyDefinition()
         */
        @Deprecated
        public Builder upstreamProxy(URI proxySpecification) {
            requireNonNull(proxySpecification, "proxySpecification");
            return upstreamProxy(UriProxySpecification.of(proxySpecification).toUpstreamProxyDefinition());
        }

        /**
         * Configures the collector to use an upstream proxy specified by a URI. The URI components
         * must be as described in {@link WebdrivingConfig#getProxySpecification()}.
         * @param proxySpecification
         * @return this builder instance
         */
        public Builder upstreamProxy(UpstreamProxyDefinition proxySpecification) {
            this.upstreamConfigurator = BmpConfigurator.usingUpstreamProxy(proxySpecification);
            return this;
        }

        /**
         * Configures the collector to post-process the captured HAR file with the given instance.
         * @param harPostProcessor
         * @return this builder instance
         */
        public Builder harPostProcessor(HarPostProcessor harPostProcessor) {
            harPostProcessors.add(requireNonNull(harPostProcessor, "harPostProcessor"));
            return this;
        }

        /**
         * Builds a collector instance.
         * @return a new collector instance
         */
        public TrafficCollector build() {
            return new TrafficCollectorImpl(webDriverFactory,
                    certificateAndKeySource, upstreamConfigurator,
                    httpFiltersSources, interceptingProxyInstantiator,
                    harPostProcessors, exceptionReactor);
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy