package net.sourceforge.javautil.developer.web.unit.mockbrowser;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import net.sourceforge.javautil.developer.web.unit.mockserver.MockServer;
import net.sourceforge.javautil.developer.web.unit.mockserver.MockServerHost;
import net.sourceforge.javautil.developer.web.unit.mockserver.MockServerResponse;
import net.sourceforge.javautil.developer.web.unit.mockserver.http.HttpUtil;
import net.sourceforge.javautil.developer.web.unit.mockserver.http.MockHttpServletContext;
import net.sourceforge.javautil.developer.web.unit.mockserver.http.MockHttpServletResponse;
import net.sourceforge.javautil.web.server.WebServerApplicationErrorEvent;
import net.sourceforge.javautil.web.server.WebServerErrorEvent;
import net.sourceforge.javautil.web.server.WebServerHost;
import net.sourceforge.javautil.web.server.impl.WebServerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The base for mock browsers that will simulate a browser to a limited extent allowing
* the processing of HTTP page request/response.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class MockBrowser extends WebServerAdapter {
protected Logger log = LoggerFactory.getLogger(getClass());
protected Map<String, String> staticResourceCache = new HashMap<String, String>();
protected MockServer server;
protected Map<String, Cookie> cookies = new LinkedHashMap<String, Cookie>();
/**
* @param server The server to send simulated requests to
*/
public MockBrowser(MockServer server) {
this.server = server;
this.server.addListener(this);
}
public MockServer getServer() { return server; }
/**
* @param request The request to process
* @return The browser response
*/
public MockBrowserResponse process (MockBrowserRequest request) {
try {
request.addHeader("User-Agent", "Mock Browser");
request.addHeader("Date", HttpUtil.format(new Date()));
request.getCookies().putAll(this.cookies);
String protocol = request.getUrl().getProtocol();
String hostname = request.getUrl().getHost();
int port = request.getUrl().getPort();
String path = request.getUrl().getPath();
WebServerHost requestHost = server.getDefaultHost();
for (WebServerHost host : server.getHosts()) {
if (host.handlesHost(hostname)) { requestHost = host; break; }
}
if (requestHost == null)
throw new MockBrowserException(request, "No host could be found to handle request", null);
MockServerHost serverHost = (MockServerHost) requestHost;
MockServerResponse serverResponse = serverHost.process(request);
MockHttpServletResponse response = (MockHttpServletResponse) serverResponse.getResponse();
for (Cookie cookie : response.getCookies()) cookies.put(cookie.getName(), cookie);
int code = response.getIntHeader("Status");
switch (code) {
case 200: case -1: return new MockBrowserResponse(serverResponse, request);
case 301: case 302: case 303: case 304: case 305: case 306: case 307:
return this.process(new MockBrowserRequest(new URL(request.getUrl(), response.getHeader("Location")), "GET"));
default:
throw new MockBrowserHttpErrorException(request, code, null, null);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override public void applicationError(WebServerApplicationErrorEvent evt) {
evt.getThrowable().printStackTrace();
}
@Override public void serverError(WebServerErrorEvent evt) {
evt.getThrowable().printStackTrace();
}
}