public void service(final HttpServletRequest servletRequest, final HttpServletResponse servletResponse) throws IOException, ServletException {
if (characterEncoding != null) {
servletRequest.setCharacterEncoding(characterEncoding);
servletResponse.setCharacterEncoding(characterEncoding);
}
HttpRequest request = injector.getInstance(HttpRequest.class);
String context = StringUtils.trimToEmpty(servletRequest.getContextPath());
String path = StringUtils.trimToEmpty(servletRequest.getRequestURI());
try {
// TODO context should always end in a trailing slash and path should always start without a slash.
path = path.substring(context.length()+1); // +1 to gobble up the trailing slash
request.setPath(path);
request.setContext(context);
request.setMethod(servletRequest.getMethod());
request.setSession(new HttpServletSession(servletRequest));
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(servletRequest);
if (isMultipart) {
Map<String, FileItem> files = new HashMap<String, FileItem>();
Map<String, String[]> parameters = new HashMap<String, String[]>();
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List<FileItem> items = upload.parseRequest(servletRequest);
// Process the uploaded items
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
parameters.put(item.getFieldName(), new String[] {item.getString()}); // TODO Allow multiple values, check to see if parameters already has a value with this name and append.
} else {
files.put(item.getFieldName(), item);
}
}
request.setFiles(files);
request.setParameterMap(parameters);
} else {
request.setParameterMap(servletRequest.getParameterMap());
request.setFiles(null);
}
if (servletRequest.getUserPrincipal() == null) {
// TODO this user should not necessarly change from request to request (maybe). only works if the user has cookies, see how django handles.
request.setUser(new AnonymousUser());
} else {
request.setUser(new PrincipalUser(servletRequest));
}
HttpResponse response = requestProcessor.service(request);
response.render(servletRequest, servletResponse);
// tell the request that we are done so it can notify any listeners. good place to close database sessions, etc.
request.close();
} catch (Http404 e) {
String level = injector.getInstance(Settings.class).get(BROKEN_LINK_LOG_LEVEL);
if (level != null) {
if ("trace".equalsIgnoreCase(level)) {
log.trace(e,e);
} else if ("debug".equalsIgnoreCase(level)) {
log.debug(e,e);
} else if ("info".equalsIgnoreCase(level)) {
log.info(e,e);
} else if ("warn".equalsIgnoreCase(level)) {
log.warn(e,e);
} else if ("error".equalsIgnoreCase(level)) {
log.error(e,e);
} else if ("fatal".equalsIgnoreCase(level)) {
log.fatal(e,e);
}
}
if (!injector.getInstance(Settings.class).isDebug()) {
// TODO ability to specify 404 handler
SimpleHttpResponse response = new SimpleHttpResponse("Page not found");
response.setStatusCode(404);
try {
response.render(servletRequest, servletResponse);
} catch (HttpException e2) {
log.error(e2,e2);
throw new ServletException(e);
}
} else {
throw new ServletException(e);
}
} catch (FileUploadException e) {
log.error(e,e);
try {
request.close();
} catch (HttpException e1) {
log.error(e1,e1);
}
// TODO Pretty print the exception and stack trace, request information, etc
if (!injector.getInstance(Settings.class).isDebug()) {
HttpResponse response = new SimpleHttpResponse("Unrecoverable error processing uploaded files, please contact support");
try {
response.render(servletRequest, servletResponse);
} catch (HttpException e2) {
log.error(e2,e2);
throw new ServletException(e);
}
}
} catch (HttpException e) {
log.error(String.format("HttpException while processing for user '%s' %s:%s", request.getUser(), context, path));
log.error(e,e);
try {
request.close();
} catch (HttpException e1) {
log.error(e1,e1);
}
// TODO Pretty print the exception and stack trace, request information, etc
// TODO can this exception be handled by middleware? middleware is not really avaliable here as it is handled in the requestProcessor...