Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1a94d51
Cleanup up synchronization handling for blacklists, whitelists, and a…
jekh Oct 25, 2014
3413b4e
Merge branch 'logger-cleanup' into synchronization-cleanup
jekh Oct 25, 2014
fba3a70
Merge branch 'logger-cleanup' into synchronization-cleanup
jekh Oct 26, 2014
a747bc6
Made modifiable fields of BrowserMobHttpClient volatile, since other …
jekh Oct 27, 2014
8ebda4e
Added server shutdown to test
jekh Oct 27, 2014
fdae546
Made UserAgentStringParser initialization on-demand, to prevent updat…
jekh Oct 27, 2014
f57526e
Minor ArrayList size addition
jekh Oct 27, 2014
71433dd
Delete unused proxies after expiration time passes
nite23 Oct 27, 2014
0cd3eff
Merge branch 'logger-cleanup' into synchronization-cleanup
jekh Oct 27, 2014
2a96069
Merge branch 'logger-cleanup' into synchronization-cleanup
jekh Oct 27, 2014
a14f70a
Merge remote-tracking branch 'upstream/master' into synchronization-c…
jekh Oct 27, 2014
116e568
Merge remote-tracking branch 'remotes/bm-gh/master' into tmp
nite23 Oct 28, 2014
cb02ee9
Added data transfer limits
nite23 Oct 28, 2014
15b4807
Documented data limit API call
nite23 Oct 28, 2014
b13ce9e
Added support for empty, enabled whitelists.
jekh Oct 29, 2014
1d2418c
Merge remote-tracking branch 'upstream/master' into synchronization-c…
jekh Oct 29, 2014
9ba1d1b
Updated uadetector to most recent version
jekh Oct 29, 2014
7b76fb8
Merge pull request #124 from neoalienson/blacklist_with_method
lightbody Nov 8, 2014
849243d
Merge pull request #118 from nite23/tmp
lightbody Nov 8, 2014
eac09a5
Merge pull request #120 from nite23/bwlimit3
lightbody Nov 8, 2014
a99c675
Extracted blacklist matching code into BlacklistEntry class.
jekh Nov 10, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ Once that is done, a new proxy will be available on the port returned. All you h
- method - regular expression for matching method., e.g., POST. Emtpy for matching all method.
- DELETE /proxy/[port]/blacklist - Clears all URL patterns from the blacklist
- PUT /proxy/[port]/limit - Limit the bandwidth through the proxy. Takes the following parameters:
- downstreamKbps - Sets the downstream kbps
- upstreamKbps - Sets the upstream kbps
- downstreamKbps - Sets the downstream bandwidth limit in kbps
- upstreamKbps - Sets the upstream bandwidth limit kbps
- downstreamMaxKB - Specifies how many kilobytes in total the client is allowed to download through the proxy.
- upstreamMaxKB - Specifies how many kilobytes in total the client is allowed to upload through the proxy.
- latency - Add the given latency to each HTTP request
- enable - (true/false) a boolean that enable bandwidth limiter. By default the limit is disabled, although setting any of the properties above will implicitly enable throttling
- payloadPercentage - a number ]0, 100] specifying what percentage of data sent is payload. e.g. use this to take into account overhead due to tcp/ip.
- maxBitsPerSecond - The max bits per seconds you want this instance of StreamManager to respect.
- GET /proxy/[port]/limit - Displays the amount of data remaining to be uploaded/downloaded until the limit is reached.
- POST /proxy/[port]/headers - Set and override HTTP Request headers. For example setting a custom User-Agent.
- Payload data should be json encoded set of headers (not url-encoded)
- POST /proxy/[port]/hosts - Overrides normal DNS lookups and remaps the given hosts with the associated IP address
Expand Down Expand Up @@ -119,12 +122,14 @@ system properties will be used to specify the upstream proxy.
Command-line Arguments
----------------------

- -port <port>
- -port \<port\>
- Port on which the API listens. Default value is 8080.
- -address <address>
- Address to which the API is bound. Default value is 0.0.0.0.
- -proxyPortRange <from>-<to>
- Range of ports reserved for proxies. Only applies if *port* parameter is not supplied in the POST request. Default values are <port>+1 to <port>+500+1.
- -proxyPortRange \<from\>-\<to\>
- Range of ports reserved for proxies. Only applies if *port* parameter is not supplied in the POST request. Default values are \<port\>+1 to \<port\>+500+1.
- -ttl \<seconds\>
- Proxy will be automatically deleted after a specified time period. Off by default.

Embedded Mode
-------------
Expand Down
22 changes: 21 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@
<developerConnection>scm:git:git@github.com:lightbody/browsermob-proxy.git</developerConnection>
<url>git@github.com:lightbody/browsermob-proxy.git</url>
</scm>

<repositories>
<repository>
<id>guiceyfruit.release</id>
<name>GuiceyFruit Release Repository</name>
<url>http://guiceyfruit.googlecode.com/svn/repo/releases/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down Expand Up @@ -249,6 +263,12 @@
<artifactId>guice-servlet</artifactId>
<version>3.0</version>
</dependency>

<dependency>
<groupId>org.guiceyfruit</groupId>
<artifactId>guiceyfruit-core</artifactId>
<version>2.0</version>
</dependency>

<dependency>
<groupId>net.jcip</groupId>
Expand Down Expand Up @@ -294,7 +314,7 @@
<dependency>
<groupId>net.sf.uadetector</groupId>
<artifactId>uadetector-resources</artifactId>
<version>2013.10</version>
<version>2014.09</version>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
Expand Down
75 changes: 56 additions & 19 deletions src/main/java/net/lightbody/bmp/proxy/BlacklistEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,64 @@

import java.util.regex.Pattern;

public class BlacklistEntry
{
private Pattern pattern;
private int responseCode;
private Pattern method;
public class BlacklistEntry {
private final Pattern pattern;
private final int responseCode;
private final Pattern method;

public BlacklistEntry(String pattern, int responseCode, String method) {
this.pattern = Pattern.compile(pattern);
this.responseCode = responseCode;
this.method = Pattern.compile(("".equals(method) || method == null) ? ".*" : method);
}
/**
* Creates a new BlacklistEntry with no HTTP method matching (i.e. all methods will match).
*
* @param pattern URL pattern to blacklist
* @param responseCode response code to return for blacklisted URL
*/
public BlacklistEntry(String pattern, int responseCode) {
this(pattern, responseCode, null);
}

/**
* Creates a new BlacklistEntry which will match both a URL and an HTTP method
*
* @param pattern URL pattern to blacklist
* @param responseCode response code to return for blacklisted URL
* @param method HTTP method to match (e.g. GET, PUT, PATCH, etc.)
*/
public BlacklistEntry(String pattern, int responseCode, String method) {
this.pattern = Pattern.compile(pattern);
this.responseCode = responseCode;
if (method == null || method.isEmpty()) {
this.method = null;
} else {
this.method = Pattern.compile(method);
}
}

/**
* Determines if this BlacklistEntry matches the given URL. Attempts to match both the URL and the
* HTTP method.
*
* @param url possibly-blacklisted URL
* @param httpMethod HTTP method this URL is being accessed with
* @return true if the URL matches this BlacklistEntry
*/
public boolean matches(String url, String httpMethod) {
if (method != null) {
return pattern.matcher(url).matches() && method.matcher(httpMethod).matches();
} else {
return pattern.matcher(url).matches();
}
}

public Pattern getPattern() {
return this.pattern;
}
public Pattern getPattern() {
return this.pattern;
}

public int getResponseCode() {
return responseCode;
}

public int getResponseCode() {
return this.responseCode;
}

public Pattern getMethod() {
return this.method;
return method;
}
}

}
29 changes: 13 additions & 16 deletions src/main/java/net/lightbody/bmp/proxy/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,6 @@
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.sitebricks.SitebricksModule;

import net.lightbody.bmp.exception.JettyException;
import net.lightbody.bmp.proxy.bricks.ProxyResource;
import net.lightbody.bmp.proxy.guice.ConfigModule;
import net.lightbody.bmp.proxy.guice.JettyModule;
import net.lightbody.bmp.proxy.util.StandardFormatter;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContextEvent;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
Expand All @@ -28,6 +14,17 @@
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import net.lightbody.bmp.exception.JettyException;
import net.lightbody.bmp.proxy.bricks.ProxyResource;
import net.lightbody.bmp.proxy.guice.ConfigModule;
import net.lightbody.bmp.proxy.guice.JettyModule;
import net.lightbody.bmp.proxy.util.StandardFormatter;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.guiceyfruit.jsr250.Jsr250Module;
import org.slf4j.LoggerFactory;

public class Main {
private static final String LOGGING_PROPERTIES_FILENAME = "conf/bmp-logging.properties";
Expand All @@ -38,7 +35,7 @@ public class Main {
public static void main(String[] args) {
configureJdkLogging();

final Injector injector = Guice.createInjector(new ConfigModule(args), new JettyModule(), new SitebricksModule() {
final Injector injector = Guice.createInjector(new ConfigModule(args), new Jsr250Module(), new JettyModule(), new SitebricksModule() {
@Override
protected void configureSitebricks() {
scan(ProxyResource.class.getPackage());
Expand Down Expand Up @@ -148,4 +145,4 @@ private static void configureDefaultLogger() {
logger.addHandler(handler);
}
}


32 changes: 27 additions & 5 deletions src/main/java/net/lightbody/bmp/proxy/ProxyManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import com.google.inject.name.Named;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.PreDestroy;

import net.lightbody.bmp.proxy.util.ExpirableMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -22,15 +24,28 @@ public class ProxyManager {
private int lastPort;
private final int minPort;
private final int maxPort;
private Provider<ProxyServer> proxyServerProvider;
private ConcurrentHashMap<Integer, ProxyServer> proxies = new ConcurrentHashMap<Integer, ProxyServer>();
private final Provider<ProxyServer> proxyServerProvider;
private final ConcurrentMap<Integer, ProxyServer> proxies;

@Inject
public ProxyManager(Provider<ProxyServer> proxyServerProvider, @Named("minPort") Integer minPort, @Named("maxPort") Integer maxPort) {
public ProxyManager(Provider<ProxyServer> proxyServerProvider, @Named("minPort") Integer minPort, @Named("maxPort") Integer maxPort, @Named("ttl") Integer ttl) {
this.proxyServerProvider = proxyServerProvider;
this.minPort = minPort;
this.maxPort = maxPort;
this.lastPort = maxPort;
this.proxies = ttl > 0 ?
new ExpirableMap<Integer, ProxyServer>(ttl, new ExpirableMap.OnExpire<ProxyServer>(){
@Override
public void run(ProxyServer proxy) {
try {
LOG.debug("Expiring ProxyServer `{}`...", proxy.getPort());
proxy.stop();
} catch (Exception ex) {
LOG.warn("Error while stopping an expired proxy", ex);
}
}
}) :
new ConcurrentHashMap<Integer, ProxyServer>();
}

public ProxyServer create(Map<String, String> options, Integer port, String bindAddr) {
Expand Down Expand Up @@ -115,4 +130,11 @@ public void delete(int port) {
ProxyServer proxy = proxies.remove(port);
proxy.stop();
}

@PreDestroy
public void stop(){
if(proxies instanceof ExpirableMap){
((ExpirableMap)proxies).stop();
}
}
}
Loading