com.github.bjuvensjo.rsimulator.http.HttpSimulator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rsimulator-http Show documentation
Show all versions of rsimulator-http Show documentation
${project.artifactId} module
package com.github.bjuvensjo.rsimulator.http;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import org.apache.commons.lang.StringUtils;
import com.github.bjuvensjo.rsimulator.core.Simulator;
import com.github.bjuvensjo.rsimulator.core.SimulatorResponse;
import com.github.bjuvensjo.rsimulator.core.config.CoreModule;
import com.github.bjuvensjo.rsimulator.http.config.Constants;
import com.github.bjuvensjo.rsimulator.http.config.GlobalConfig;
import com.github.bjuvensjo.rsimulator.http.config.HttpModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* HttpSimulator makes the {@link Simulator} functionality available over http.
*
* @author Magnus Bjuvensjö
*/
public class HttpSimulator extends javax.servlet.http.HttpServlet {
private static final long serialVersionUID = -3272134329745138875L;
private static final int BUFFER_SIZE = 1000;
private static final Pattern CHARSET_PATTERN = Pattern.compile("charset=([0-9A-Z-]+)");
private static final Pattern ACCEPT_PATTERN = Pattern.compile("([^;]+)");
private static final Pattern CONTENT_TYPE_PATTERN = Pattern.compile("([^;]+)");
private static Logger log = LoggerFactory.getLogger(HttpSimulator.class);
@Inject
private Simulator simulator;
@Inject
@Named("simulatorContentTypes")
private Map simulatorContentTypes;
@Inject
@Named("accepts")
private Map accepts;
@Inject
@Named("responseContentTypes")
private Map responseContentTypes;
/**
* {@inheritDoc}
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
Injector injector = Guice.createInjector(new CoreModule(), new HttpModule());
injector.injectMembers(this);
}
/**
* {@inheritDoc}
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String theRootPath = request.getParameter(Constants.ROOT_PATH);
String theUseRootRelativePath = request.getParameter(Constants.USE_ROOT_RELATIVE_PATH);
if (theRootPath != null || theUseRootRelativePath != null) {
if (theRootPath != null) {
GlobalConfig.rootPath = theRootPath;
}
if (theUseRootRelativePath != null) {
GlobalConfig.useRootRelativePath = "true".equals(theUseRootRelativePath);
}
String message = new StringBuilder().append("[").append("rootPath: ").append(theRootPath).append(", ")
.append("useRootRelativePath: ").append(theUseRootRelativePath).append("]").toString();
log.debug("message: {}", message);
response.getWriter().write(message);
} else {
handle(request, response);
}
}
/**
* {@inheritDoc}
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handle(request, response);
}
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handle(request, response);
}
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handle(request, response);
}
private void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String rootPath = getRequestRootPath(request);
boolean useRootRelativePath = getRequestUseRootRelativePath(request);
String contentType = request.getContentType();
String accept = request.getHeader("Accept");
String charsetName = getCharsetName(contentType);
String simulatorRequest = getSimulatorRequest(request, charsetName);
String requestURI = request.getRequestURI();
String rootRelativePath = useRootRelativePath ? requestURI : "";
String simulatorContentType = getSimulatorContentType(contentType, accept);
Map vars = (Map) request.getAttribute(Constants.VARS);
log.debug("contentType: {}", contentType);
log.debug("accept: {}", accept);
log.debug("charsetName: {}", charsetName);
log.debug("method: {}", request.getMethod());
log.debug("requestBody: {}", simulatorRequest);
log.debug("requestURI: {}", requestURI);
log.debug("rootRelativePath: {}", rootRelativePath);
log.debug("rootPath: {}", rootPath);
log.debug("simulatorContentType: {}", simulatorContentType);
log.debug("vars: {}", vars);
Optional simulatorResponseOptional = simulator.service(rootPath, rootRelativePath, simulatorRequest, simulatorContentType, vars);
request.setAttribute(Constants.SIMULATOR_RESPONSE, simulatorResponseOptional.get());
String responseBody = simulatorResponseOptional.map(SimulatorResponse::getResponse).orElse("No simulatorResponse found!");
String responseContentType = getResponseContentType(simulatorContentType);
String responseCharacterEncoding = charsetName;
log.debug("responseBody: {}", responseBody);
log.debug("responseContentType: {}", responseContentType);
log.debug("responseCharacterEncoding: {}", responseCharacterEncoding);
response.setContentType(responseContentType);
response.setDateHeader("Date", System.currentTimeMillis());
response.setCharacterEncoding(responseCharacterEncoding);
simulatorResponseOptional
.flatMap(simulatorResponse -> simulatorResponse.getProperties())
.ifPresent(properties -> handleResponseProperties(response, properties));
response.getOutputStream().write(responseBody.getBytes(charsetName));
} catch (Exception e) {
log.error(null, e);
response.getWriter().write(e.getMessage());
}
}
private String getRequestRootPath(HttpServletRequest request) {
Object rootPath = request.getAttribute(Constants.ROOT_PATH);
if (rootPath instanceof String && !StringUtils.isBlank((String) rootPath)) {
return (String) rootPath;
}
return GlobalConfig.rootPath;
}
private boolean getRequestUseRootRelativePath(HttpServletRequest request) {
Object useRootRelativePath = request.getAttribute(Constants.USE_ROOT_RELATIVE_PATH);
if (useRootRelativePath != null && useRootRelativePath instanceof Boolean) {
return (Boolean) useRootRelativePath;
}
return GlobalConfig.useRootRelativePath;
}
private String getSimulatorRequest(HttpServletRequest request, String charsetName) throws IOException {
String simulatorRequest = readBody(new BufferedInputStream(request.getInputStream()), charsetName);
if (!"".equals(simulatorRequest)) {
return simulatorRequest;
}
return copyQueryString(request);
}
private void handleResponseProperties(HttpServletResponse response, Properties properties) {
log.debug("properties: {}", properties);
if (properties != null) {
String responseCode = properties.getProperty("responseCode");
log.debug("responseCode: {}", responseCode);
if (responseCode != null) {
response.setStatus(Integer.parseInt(responseCode));
}
}
}
private String readBody(BufferedInputStream bis, String charsetName) throws IOException {
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[BUFFER_SIZE];
int n = -1;
while ((n = bis.read(buffer)) > 0) {
sb.append(new String(buffer, 0, n, charsetName));
}
return sb.toString();
}
private String getSimulatorContentType(String contentType, String accept) {
String result = null;
if (contentType != null) {
Matcher m = CONTENT_TYPE_PATTERN.matcher(contentType);
if (m.find()) {
result = simulatorContentTypes.get(m.group(1));
}
}
if (result == null) {
if (accept != null) {
Matcher m = ACCEPT_PATTERN.matcher(accept);
if (m.find()) {
String[] split = m.group(1).split(" *, *");
for (int i = 0; result == null && i < split.length; i++) {
result = accepts.get(split[i]);
}
}
}
}
if (result == null) {
result = simulatorContentTypes.get("default");
}
return result;
}
private String getResponseContentType(String simulatorContentType) {
String responseContentType = responseContentTypes.get(simulatorContentType);
if (responseContentType == null) {
responseContentType = responseContentTypes.get("default");
}
return responseContentType;
}
private String copyQueryString(HttpServletRequest request) {
return request.getQueryString() == null ? "" : request.getQueryString();
}
private String getCharsetName(String contentType) {
String result = "UTF-8";
if (contentType != null) {
Matcher m = CHARSET_PATTERN.matcher(contentType);
if (m.find()) {
result = m.group(1);
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy