/* * JBoss, Home of Professional Open Source * Copyright 2009, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.arquillian.warp.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import org.jboss.arquillian.warp.ServerAssertion; import org.jboss.arquillian.warp.filter.WarpFilter; import org.jboss.arquillian.warp.utils.SerializationUtils; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponse; import org.littleshoot.proxy.DefaultHttpProxyServer; import org.littleshoot.proxy.HttpFilter; import org.littleshoot.proxy.HttpProxyServer; import org.littleshoot.proxy.HttpRequestFilter; /** * The holder for instantiated proxies. * * @author Lukas Fryc * */ public class ProxyHolder { private static Logger log = Logger.getLogger("Proxy"); private Map<URL, HttpProxyServer> servers = new HashMap<URL, HttpProxyServer>(); public void startProxyForUrl(URL proxyUrl, URL realUrl) { if (servers.containsKey(proxyUrl)) { return; } Map<String, HttpFilter> responseFilters = createResponseFilters(realUrl); HttpRequestFilter requestFilter = createRequestFilter(); HttpProxyServer server = new DefaultHttpProxyServer(proxyUrl.getPort(), responseFilters, realUrl.getHost() + ":" + realUrl.getPort(), null, requestFilter); server.start(); servers.put(proxyUrl, server); } public void freeAllProxies() { for (HttpProxyServer server : servers.values()) { server.stop(); } servers.clear(); } private HttpRequestFilter createRequestFilter() { return new HttpRequestFilter() { @Override public void filter(HttpRequest request) { if (AssertionHolder.isWaitingForProcessing()) { try { ServerAssertion assertion = AssertionHolder.popRequest(); String requestEnrichment = SerializationUtils.serializeToBase64(assertion); request.setHeader(WarpFilter.ENRICHMENT_REQUEST, Arrays.asList(requestEnrichment)); } catch (Exception e) { log.severe("enriching request failed: " + e.getMessage()); } } } }; } private Map<String, HttpFilter> createResponseFilters(final URL realUrl) { final HttpFilter filter = new HttpFilter() { @Override public boolean shouldFilterResponses(HttpRequest httpRequest) { return true; } @Override public int getMaxResponseSize() { return Integer.MAX_VALUE; } @Override public HttpResponse filterResponse(HttpResponse response) { String responseEnrichment = response.getHeader(WarpFilter.ENRICHMENT_RESPONSE); if (responseEnrichment != null) { ServerAssertion assertion = SerializationUtils.deserializeFromBase64(responseEnrichment); AssertionHolder.pushResponse(assertion); } return response; } }; String key = realUrl.getHost() + ":" + realUrl.getPort(); Map<String, HttpFilter> map = new HashMap<String, HttpFilter>(); map.put(key, filter); return map; } @SuppressWarnings("unchecked") public Map<String, HttpFilter> getSingleEntryMap(final HttpFilter filter) { return (Map<String, HttpFilter>) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { Map.class }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("get".equals(method.getName())) { return filter; } if ("isEmpty".equals(method.getName())) { return false; } throw new UnsupportedOperationException(); } }); } }