Extension for LittleProxy that makes it easy to edit responses before forwarding them to the client.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
littleproxy-response-modifier
LICENSE
README.md

README.md

LittleProxy Response Modifier

Extension for LittleProxy that makes it easy to edit responses before forwarding them to the client.

There are many requests for how to set up LittleProxy as a reverse proxy, and especially how to edit responses before forwarding them to the client. This extension allows you to:

  • Quickly set up a LittleProxy implementation that intercepts and edits server responses.
  • Edit responses through regular expressions or XSLT (or through your own implementation).

Check out the ReverseProxy example to see how to set up this extension with a reverse proxy.

Installation (Maven)

Repository

<dependency>
	<groupId>nl.michielmeulendijk</groupId>
	<artifactId>lprm</artifactId>
	<version>1.0.2</version>
</dependency>

Dependencies

<!-- original LittleProxy dependency -->
<dependency>
	<groupId>org.littleshoot</groupId>
	<artifactId>littleproxy</artifactId>
	<version>1.1.2</version>
</dependency>

<!-- Xalan is required if XSLTResponseModifierAdapter is used -->
<dependency>
	<groupId>xalan</groupId>
	<artifactId>xalan</artifactId>
	<version>2.7.2</version>
</dependency>

How to use

Use the repository as follows:

  • Add and override ResponseModifierSourceAdapter as FiltersSource
  • Override filterRequest to return an class implementing ResponseModifierAdapter. Out of the box RegExResponseModifierAdapter and XSLTResponseModifierAdapter are available.
  • The class implementing ResponseModifierAdapter accepts as final argument any number of URLFilter classes. Use the appropriate subclass to set up your filters. All filters contain a condition (i.e. a RegEx string to which URLs will be matched) and an action (i.e. an object that determines how the response will be edited).

An example of use with RegExResponseModifierAdapter:

HttpProxyServer server =
	DefaultHttpProxyServer.bootstrap()
		.withPort(8080)
		.withFiltersSource(
			new ResponseModifierSourceAdapter() {
				@Override
				public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
					return new RegExResponseModifierAdapter(
						originalRequest, ctx,
						//set up URL filter
						new RegExURLFilter(
							//any URL matching this regex will invoke the filter's action 
							"^/testpage.html",
							//all HashMap entries contain a regex (key) that will be replaced with another
							//string (value) throughout the response text
							new HashMap<String, String>() {{
								//replace the title
								put("<title>.*<\\/title>", "<title>New Title!</title>");
								//append a paragraph to the body
								put("<body>", "<body><p>Hello world!</p>");
							}}
						)
					)
				}
			}
		).start()

An example of use with XSLTResponseModifierAdapter:

HttpProxyServer server =
  DefaultHttpProxyServer.bootstrap()
  	.withPort(8080)
  	.withFiltersSource(
  		new ResponseModifierSourceAdapter() {
  			@Override
  			public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
  				return new XSLTResponseModifierAdapter(
  					originalRequest, ctx,
  					//set up URL filter
  					new XSLTURLFilter(
  						//any URL matching this regex will invoke the filter's action 
  						"^/testpage.html",
  						//an InputStream containing the XSL document with which the response will be transformed
  						this.getClass().getClassLoader().getResourceAsStream("transform-testpage.xsl"),
  						true
  					)
  				)
  			}
  		}
  	).start()

XSLTResponseModifierAdapter uses Xalan to perform its XSL transformations. Make sure you include it as a dependency if you go this route.

Configuration

The code overrides serverToProxyResponse, checks if the request URL matches any URLFilters, and changes them if required. If you need to intercept the response after any of the filters, I recommend using proxyToClientResponse so as not to get in the way of the response modifier.

By default, getMaximum(Request/Response)BufferSizeInBytes returns +/- 10 MB buffers. If you need requests or responses larger than that, make sure to override them.

For an example of how to use the response modifier with a reverse proxy (including overriding example), check out the ReverseProxy class.