/*
* Copyright 2012 Future Systems
*
* 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.krakenapps.httpd;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.krakenapps.httpd.impl.Request;
import org.krakenapps.httpd.impl.Response;
import org.krakenapps.httpd.impl.ServletContextImpl;
import org.krakenapps.httpd.impl.ServletMatchResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpContext {
private final Logger logger = LoggerFactory.getLogger(HttpContext.class.getName());
private String name;
private ServletContextImpl servletContext;
private WebSocketManager webSocketManager;
private ConcurrentMap<String, HttpSession> httpSessions;
public HttpContext(String name) {
this.name = name;
this.servletContext = new ServletContextImpl(name, "/", "");
this.webSocketManager = new WebSocketManager();
this.httpSessions = new ConcurrentHashMap<String, HttpSession>();
}
public HttpContext(String name, String contextPath) {
this.name = name;
this.servletContext = new ServletContextImpl(name, contextPath, "");
this.webSocketManager = new WebSocketManager();
this.httpSessions = new ConcurrentHashMap<String, HttpSession>();
}
public void handle(Request request, Response response) throws IOException {
request.setHttpContext(this);
HttpServlet servlet = null;
String pathInfo = null;
String uri = request.getRequestURI();
logger.trace("kraken httpd: request [{} {}]", request.getMethod(), uri);
try {
String servletPath = null;
ServletMatchResult r = servletContext.matches(uri);
if (webSocketManager.getPath().equals(uri)) {
servlet = webSocketManager.getServlet();
servletPath = webSocketManager.getPath();
pathInfo = uri.substring(uri.indexOf(servletPath) + servletPath.length());
} else if (r != null) {
servlet = (HttpServlet) r.getServlet();
pathInfo = r.getPathInfo();
servletPath = r.getServletPath();
} else {
String contextPath = request.getContextPath();
if (!contextPath.equals("")) {
request.setPathInfo(uri.substring(uri.indexOf(contextPath) + contextPath.length()));
} else {
request.setPathInfo(uri);
}
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
logger.trace("kraken httpd: servlet path is [{}]", servletPath);
request.setServletPath(servletPath);
request.setPathInfo(pathInfo);
servlet.service(request, response);
} catch (FileNotFoundException e) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (Throwable t) {
logger.error("kraken httpd: servlet error", t);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (response != null && !request.isAsyncStarted())
response.close();
}
}
public String getName() {
return name;
}
public ServletContext getServletContext() {
return servletContext;
}
public WebSocketManager getWebSocketManager() {
return webSocketManager;
}
public ConcurrentMap<String, HttpSession> getHttpSessions() {
return httpSessions;
}
public void addServlet(String name, Servlet servlet, String... urlPatterns) {
servletContext.addServlet(name, servlet);
ServletRegistration reg = servletContext.getServletRegistration(name);
reg.addMapping(urlPatterns);
}
public boolean removeServlet(String name) {
return servletContext.removeServlet(name);
}
@Override
public String toString() {
return "HTTP Context [" + name + ", sessions=" + httpSessions.size() + "]\n>>\n" + servletContext + webSocketManager;
}
}