Skip to content
This repository was archived by the owner on Feb 24, 2026. It is now read-only.
Closed
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
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.org/adamfisk/LittleProxy.png?branch=master)](https://travis-ci.org/adamfisk/LittleProxy)
[![CircleCI](https://circleci.com/gh/verygoodsecurity/LittleProxy.svg?style=svg)](https://circleci.com/gh/verygoodsecurity/LittleProxy)

LittleProxy is a high performance HTTP proxy written in Java atop Trustin Lee's excellent [Netty](http://netty.io) event-based networking library. It's quite stable, performs well, and is easy to integrate into your projects.

Expand Down
33 changes: 33 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
machine:
java:
version: oraclejdk8
environment:
AWS_PROFILE: vgs-dev
RELEASE_BRANCH: vgs-edition
dependencies:
override:
- ./env.sh
- mvn clean dependency:go-offline install -Dmaven.test.skip=true --fail-never --threads 5 -B
test:
override:
- ./scripts/run_circle_tests.sh
deployment:
snapshot:
branch: vgs-edition
owner: verygoodsecurity
commands:
- mvn deploy -DskipTests=true
release:
tag: /.*/
commands:
- git config user.name "circleci"
- git config user.email "circleci@vgs.com"
- git fetch
- git checkout $RELEASE_BRANCH
- git pull origin $RELEASE_BRANCH
- git reset --hard
- git tag -d $CIRCLE_TAG
- mvn -B -X -e gitflow:release-start -DreleaseVersion=$CIRCLE_TAG
- mvn -B -X -e gitflow:release-finish -DreleaseVersion=$CIRCLE_TAG -DpostReleaseGoals='deploy -DskipTests'
- git push origin $RELEASE_BRANCH
14 changes: 14 additions & 0 deletions env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

set -x

mkdir -p ~/.aws
touch ~/.aws/credentials

echo "
[vgs-dev]
region = us-west-2
role_arn = arn:aws:iam::883127560329:role/StageDeploy
source_profile = default
" | tee -a ~/.aws/credentials

151 changes: 134 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<groupId>org.littleshoot</groupId>
<artifactId>littleproxy</artifactId>
<packaging>jar</packaging>
<version>1.1.3-SNAPSHOT</version>
<version>1.1.6.0-VGS-SNAPSHOT</version>
<name>LittleProxy</name>
<description>
LittleProxy is a high performance HTTP proxy written in Java and using the Netty networking framework.
Expand Down Expand Up @@ -54,16 +54,65 @@
</scm>

<distributionManagement>

<repository>
<id>vg-release</id>
<name>VG Release Repository</name>
<url>s3://vault-dev-01-audits-01-artifact-19k6160zpr44j/software/release/</url>
</repository>

<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<id>vg-snapshot</id>
<name>VG Snapshot Repository</name>
<url>s3://vault-dev-01-audits-01-artifact-19k6160zpr44j/software/snapshot/</url>
</snapshotRepository>

</distributionManagement>

<pluginRepositories>
<pluginRepository>
<id>jfog</id>
<name>jfrog</name>
<url>https://dl.bintray.com/vg/vgs-oss</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<repositories>

<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
<id>jcenter</id>
<name>jcenter</name>
<url>https://jcenter.bintray.com/</url>
</repository>

<repository>
<id>verygood-release-repo</id>
<name>Very Good Release Repository</name>
<url>s3://vault-dev-01-audits-01-artifact-19k6160zpr44j/software/release/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</distributionManagement>

<repository>
<id>verygood-snapshot-repo</id>
<name>Very Good Snapshot Repository</name>
<url>s3://vault-dev-01-audits-01-artifact-19k6160zpr44j/software/snapshot/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>

</repositories>

<inceptionYear>2009</inceptionYear>

Expand All @@ -84,7 +133,7 @@
<jdk>[,1.8)</jdk>
</activation>
<properties>
<javadoc.opts />
<javadoc.opts/>
</properties>
</profile>

Expand Down Expand Up @@ -160,15 +209,9 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
</configuration>
<groupId>com.amashchenko.maven.plugin</groupId>
<artifactId>gitflow-maven-plugin</artifactId>
<version>1.8.0</version>
</plugin>
</plugins>
</build>
Expand All @@ -186,7 +229,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
<version>23.0</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -454,6 +497,12 @@
<version>2.5.2</version>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand All @@ -465,6 +514,12 @@
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>

<plugin>
<groupId>com.amashchenko.maven.plugin</groupId>
<artifactId>gitflow-maven-plugin</artifactId>
<version>1.8.0</version>
</plugin>
</plugins>
</pluginManagement>

Expand Down Expand Up @@ -504,6 +559,59 @@
</configuration>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<VGS-LittleProxy-Revision>${buildNumber}</VGS-LittleProxy-Revision>
</manifestEntries>
</archive>
</configuration>
</plugin>

<plugin>
<groupId>com.amashchenko.maven.plugin</groupId>
<artifactId>gitflow-maven-plugin</artifactId>
<version>1.8.0</version>
<configuration>
<verbose>true</verbose>
<versionDigitToIncrement>2</versionDigitToIncrement>
<releaseRebase>true</releaseRebase>
<pushRemote>false</pushRemote>
<skipTestProject>true</skipTestProject>
<allowSnapshots>true</allowSnapshots>
<gitFlowConfig>
<productionBranch>vgs-edition</productionBranch>
<developmentBranch>vgs-edition</developmentBranch>
<releaseBranchPrefix>release-</releaseBranchPrefix>
<versionTagPrefix></versionTagPrefix>
</gitFlowConfig>
<commitMessages>
<releaseStartMessage>update versions for @{version} release</releaseStartMessage>
<releaseFinishMessage>update for next development version @{version}</releaseFinishMessage>
</commitMessages>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down Expand Up @@ -550,6 +658,15 @@
</executions>
</plugin>
</plugins>

<extensions>
<extension>
<groupId>io.vgs.tools</groupId>
<artifactId>aws-maven</artifactId>
<version>1.4.3</version>
</extension>
</extensions>

</build>

<reporting>
Expand Down
6 changes: 6 additions & 0 deletions scripts/run_circle_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

if [ "$CIRCLE_TAG" == "" ]
then
mvn test -T2C
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.littleshoot.proxy;

import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import org.littleshoot.proxy.impl.ProxyUtils;

public class DefaultFailureHttpResponseComposer implements FailureHttpResponseComposer {

/**
* Tells the client that something went wrong trying to proxy its request. If the Bad Gateway is a response to
* an HTTP HEAD request, the response will contain no body, but the Content-Length header will be set to the
* value it would have been if this 502 Bad Gateway were in response to a GET.
*
* @param httpRequest the HttpRequest that is resulting in the Bad Gateway response
* @param cause raised exception
* @return true if the connection will be kept open, or false if it will be disconnected
*/
@Override
public FullHttpResponse compose(HttpRequest httpRequest, Throwable cause) {
String body = provideCustomMessage(httpRequest, cause);
HttpResponseStatus status = provideCustomStatus(httpRequest, cause);

FullHttpResponse response = ProxyUtils.createFullHttpResponse(HttpVersion.HTTP_1_1, status, body);

if (ProxyUtils.isHEAD(httpRequest)) {
// don't allow any body content in response to a HEAD request
response.content().clear();
}
return response;
}

/**
* The method can be overridden to provide a custom message along with 502 code
* @param httpRequest initial request
* @param cause an exception thrown on a failure
* @return custom message
*/
protected String provideCustomMessage(HttpRequest httpRequest, Throwable cause) {
return "Bad Gateway: " + httpRequest.getUri();
}

protected HttpResponseStatus provideCustomStatus(HttpRequest httpRequest, Throwable cause) {
return HttpResponseStatus.BAD_GATEWAY;
}
}
11 changes: 11 additions & 0 deletions src/main/java/org/littleshoot/proxy/ExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.littleshoot.proxy;

public interface ExceptionHandler {

/**
* Handles proxy exceptions
*
* @param cause error cause
*/
void handle(Throwable cause);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.littleshoot.proxy;

import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;

/**
* Interface for objects that can provide a custom http response on a specific failure.
*/
public interface FailureHttpResponseComposer {

/**
* Creates an {@link FullHttpResponse} based on initial request and failure cause
* @param httpRequest initial request
* @param cause an exception thrown during a failure
* @return failure http response
*/
FullHttpResponse compose(HttpRequest httpRequest, Throwable cause);
}
28 changes: 28 additions & 0 deletions src/main/java/org/littleshoot/proxy/GlobalStateHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.littleshoot.proxy;

import io.netty.channel.Channel;

/**
* Netty is not designed for thread local or global state usage.
* It guarantees that a channel is handled by only one thread
* but that thread is constantly reused by other channels so
* the state can be messed up.
*
* This handler lets serialize the state to a channel so it
* can be deserialized when needed.
*/
public interface GlobalStateHandler {

/**
* Deserializes global state from channel.
*
* @param channel client connection channel
*/
void restoreFromChannel(Channel channel);

/**
* Clears global state.
*/
void clear();

}
Loading