Skip to content

Commit

Permalink
split proxy-specific code out of Recorder
Browse files Browse the repository at this point in the history
  • Loading branch information
robfletcher committed Sep 26, 2012
1 parent c2a3dfe commit e0451a9
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 80 deletions.
11 changes: 11 additions & 0 deletions src/main/groovy/co/freeside/betamax/HttpInterceptor.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package co.freeside.betamax

interface HttpInterceptor {

boolean isRunning()

void start()

void stop()

}
48 changes: 2 additions & 46 deletions src/main/groovy/co/freeside/betamax/Recorder.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ class Recorder implements MethodRule {
}

private StorableTape tape
private ProxyServer proxy = new ProxyServer()
private final ProxyOverrider proxyOverrider = new ProxyOverrider()
private final SSLOverrider sslOverrider = new SSLOverrider()
private final HttpInterceptor proxy = new ProxyServer(this)

/**
* Inserts a tape either creating a new one or loading an existing file from `tapeRoot`.
Expand All @@ -130,17 +128,9 @@ class Recorder implements MethodRule {
* @return the active _tape_.
*/
Tape getTape() {
// TODO: throw ISE if no tape
tape
}

/**
* @return the proxy overrider used by this recorder.
*/
ProxyOverrider getProxyOverrider() {
proxyOverrider
}

/**
* 'Ejects' the current _tape_, writing its content to file. If the proxy is active after calling this method it
* will no longer record or play back any HTTP traffic until another tape is inserted.
Expand Down Expand Up @@ -200,17 +190,12 @@ class Recorder implements MethodRule {

private void startProxy(String tapeName, Map arguments) {
if (!proxy.running) {
proxy.port = proxyPort
proxy.start(this)
proxy.start()
}
insertTape(tapeName, arguments)
overrideProxySettings()
overrideSSLSettings()
}

private void stopProxy() {
restoreOriginalProxySettings()
restoreOriginalSSLSettings()
proxy.stop()
ejectTape()
}
Expand Down Expand Up @@ -240,33 +225,4 @@ class Recorder implements MethodRule {
sslSupport = config.betamax.sslSupport
}

void overrideProxySettings() {
def proxyHost = InetAddress.localHost.hostAddress
def nonProxyHosts = ignoreHosts as Set
if (ignoreLocalhost) {
def local = InetAddress.localHost
nonProxyHosts << local.hostName
nonProxyHosts << local.hostAddress
nonProxyHosts << 'localhost'
nonProxyHosts << '127.0.0.1'
}
proxyOverrider.activate proxyHost, proxyPort, nonProxyHosts
}

void restoreOriginalProxySettings() {
proxyOverrider.deactivateAll()
}

void overrideSSLSettings() {
if (sslSupport) {
sslOverrider.activate()
}
}

void restoreOriginalSSLSettings() {
if (sslSupport) {
sslOverrider.deactivate()
}
}

}
60 changes: 54 additions & 6 deletions src/main/groovy/co/freeside/betamax/proxy/jetty/ProxyServer.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@

package co.freeside.betamax.proxy.jetty

import co.freeside.betamax.Recorder
import co.freeside.betamax.*
import co.freeside.betamax.proxy.handler.*
import co.freeside.betamax.ssl.DummySSLSocketFactory
import co.freeside.betamax.util.*
import org.apache.http.client.HttpClient
import org.apache.http.conn.scheme.Scheme
import org.apache.http.impl.client.DefaultHttpClient
Expand All @@ -29,13 +30,20 @@ import org.eclipse.jetty.server.*
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector
import static co.freeside.betamax.Recorder.DEFAULT_PROXY_PORT

class ProxyServer extends SimpleServer {
class ProxyServer extends SimpleServer implements HttpInterceptor {

ProxyServer() {
private final Recorder recorder
private final ProxyOverrider proxyOverrider = new ProxyOverrider()
private final SSLOverrider sslOverrider = new SSLOverrider()

ProxyServer(Recorder recorder) {
super(DEFAULT_PROXY_PORT)
this.recorder = recorder
}

void start(Recorder recorder) {
void start() {
port = recorder.proxyPort

def handler = new BetamaxProxy()
handler <<
new TapeReader(recorder) <<
Expand All @@ -46,14 +54,24 @@ class ProxyServer extends SimpleServer {
def connectHandler = new CustomConnectHandler(handler, port + 1)

super.start(connectHandler)

overrideProxySettings()
overrideSSLSettings()
}

@Override
void stop() {
restoreOriginalProxySettings()
restoreOriginalSSLSettings()
super.stop()
}

private HttpClient newHttpClient(Recorder recorder) {
def connectionManager = new ThreadSafeClientConnManager()
def connectionManager = new ThreadSafeClientConnManager() // TODO: use non-deprecated impl
def httpClient = new DefaultHttpClient(connectionManager)
httpClient.routePlanner = new ProxySelectorRoutePlanner(
httpClient.connectionManager.schemeRegistry,
recorder.proxyOverrider.originalProxySelector
proxyOverrider.originalProxySelector
)
if (recorder.sslSupport) {
connectionManager.schemeRegistry.register new Scheme('https', DummySSLSocketFactory.instance, 443)
Expand All @@ -78,5 +96,35 @@ class ProxyServer extends SimpleServer {
keyPassword: 'password'
)
}

void overrideProxySettings() {
def proxyHost = InetAddress.localHost.hostAddress
def nonProxyHosts = recorder.ignoreHosts as Set
if (recorder.ignoreLocalhost) {
def local = InetAddress.localHost
nonProxyHosts << local.hostName
nonProxyHosts << local.hostAddress
nonProxyHosts << 'localhost'
nonProxyHosts << '127.0.0.1'
}
proxyOverrider.activate proxyHost, port, nonProxyHosts
}

void restoreOriginalProxySettings() {
proxyOverrider.deactivateAll()
}

void overrideSSLSettings() {
if (recorder.sslSupport) {
sslOverrider.activate()
}
}

void restoreOriginalSSLSettings() {
if (recorder.sslSupport) {
sslOverrider.deactivate()
}
}

}

12 changes: 3 additions & 9 deletions src/test/groovy/co/freeside/betamax/proxy/IgnoreHostsSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class IgnoreHostsSpec extends Specification {
@Shared @AutoCleanup('deleteDir') File tapeRoot = new File(System.properties.'java.io.tmpdir', 'tapes')
@Shared @AutoCleanup('stop') SimpleServer endpoint = new SimpleServer()
@AutoCleanup('ejectTape') Recorder recorder = new Recorder(tapeRoot: tapeRoot)
@AutoCleanup('stop') ProxyServer proxy = new ProxyServer()
@AutoCleanup('stop') ProxyServer proxy = new ProxyServer(recorder)
RESTClient http

void setupSpec() {
Expand All @@ -31,15 +31,10 @@ class IgnoreHostsSpec extends Specification {
recorder.insertTape('ignore hosts spec')
}

void cleanup() {
recorder.restoreOriginalProxySettings()
}

void 'does not proxy a request to #requestURI when ignoring #ignoreHosts'() {
given: 'proxy is configured to ignore local connections'
recorder.ignoreHosts = [ignoreHosts]
proxy.start(recorder)
recorder.overrideProxySettings()
proxy.start()

when: 'a request is made'
def response = http.get(uri: requestURI)
Expand All @@ -61,8 +56,7 @@ class IgnoreHostsSpec extends Specification {
void 'does not proxy a request to #requestURI when ignoreLocalhost is true'() {
given: 'proxy is configured to ignore local connections'
recorder.ignoreLocalhost = true
proxy.start(recorder)
recorder.overrideProxySettings()
proxy.start()

when: 'a request is made'
def response = http.get(uri: requestURI)
Expand Down
7 changes: 3 additions & 4 deletions src/test/groovy/co/freeside/betamax/proxy/NoTapeSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ import static java.net.HttpURLConnection.HTTP_FORBIDDEN
@Issue('https://github.com/robfletcher/betamax/issues/18')
class NoTapeSpec extends Specification {

@Shared @AutoCleanup('restoreOriginalProxySettings') Recorder recorder = new Recorder()
@Shared @AutoCleanup('stop') ProxyServer proxy = new ProxyServer()
@Shared Recorder recorder = new Recorder()
@Shared @AutoCleanup('stop') ProxyServer proxy = new ProxyServer(recorder)
@Shared @AutoCleanup('stop') SimpleServer endpoint = new SimpleServer()
RESTClient http

void setupSpec() {
proxy.start(recorder)
recorder.overrideProxySettings()
proxy.start()
endpoint.start(EchoHandler)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,20 @@ class ProxyRecordAndPlaybackSpec extends Specification {

@Shared @AutoCleanup('deleteDir') File tapeRoot = new File(System.properties.'java.io.tmpdir', 'tapes')
@Shared @AutoCleanup('ejectTape') Recorder recorder = new Recorder(tapeRoot: tapeRoot)
@Shared @AutoCleanup('stop') ProxyServer proxy = new ProxyServer()
@Shared @AutoCleanup('stop') ProxyServer proxy = new ProxyServer(recorder)
@AutoCleanup('stop') SimpleServer endpoint = new SimpleServer()
RESTClient http

void setupSpec() {
recorder.insertTape('proxy record and playback spec')
proxy.start(recorder)
recorder.overrideProxySettings()
proxy.start()
}

void setup() {
http = new RESTClient(endpoint.url)
BetamaxRoutePlanner.configure(http.client)
}

void cleanupSpec() {
recorder.restoreOriginalProxySettings()
}

@Timeout(10)
void 'proxy makes a real HTTP request the first time it gets a request for a URI'() {
given:
Expand Down Expand Up @@ -109,7 +104,7 @@ interactions:

when:
recorder.insertTape('existing_tape')
proxy.start(recorder)
proxy.start()

then:
recorder.tape.name == 'existing_tape'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ class TapeModeSpec extends Specification {

@Shared @AutoCleanup('deleteDir') File tapeRoot = new File(System.properties.'java.io.tmpdir', 'tapes')
@Shared Recorder recorder = new Recorder(tapeRoot: tapeRoot)
@Shared @AutoCleanup('stop') ProxyServer proxy = new ProxyServer()
@Shared @AutoCleanup('stop') ProxyServer proxy = new ProxyServer(recorder)
@Shared @AutoCleanup('stop') SimpleServer endpoint = new SimpleServer()
RESTClient http

void setupSpec() {
tapeRoot.mkdirs()
proxy.start(recorder)
recorder.overrideProxySettings()
proxy.start()
endpoint.start(EchoHandler)
}

Expand All @@ -40,10 +39,6 @@ class TapeModeSpec extends Specification {
recorder.ejectTape()
}

void cleanupSpec() {
recorder.restoreOriginalProxySettings()
}

void 'in read-only mode the proxy rejects a request if no recorded interaction exists'() {
given: 'a read-only tape is inserted'
recorder.insertTape('read only tape', [mode: READ_ONLY])
Expand Down

0 comments on commit e0451a9

Please sign in to comment.