]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java
Improve logging and warnings.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / NodeHttp.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.io.IOException;
4 import java.security.cert.X509Certificate;
5 import java.util.Enumeration;
6
7 import javax.servlet.FilterChain;
8 import javax.servlet.ServletException;
9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import javax.servlet.http.HttpSession;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.argeo.cms.CmsException;
17 import org.argeo.jcr.ArgeoJcrConstants;
18 import org.eclipse.equinox.http.servlet.ExtendedHttpService;
19
20 /**
21 * Intercepts and enriches http access, mainly focusing on security and
22 * transactionality.
23 */
24 class NodeHttp implements KernelConstants, ArgeoJcrConstants {
25 private final static Log log = LogFactory.getLog(NodeHttp.class);
26
27 // Filters
28 // private final RootFilter rootFilter;
29
30 // private final DoSFilter dosFilter;
31 // private final QoSFilter qosFilter;
32
33 NodeHttp(ExtendedHttpService httpService) {
34 // rootFilter = new RootFilter();
35 // dosFilter = new CustomDosFilter();
36 // qosFilter = new QoSFilter();
37
38 try {
39 httpService.registerServlet("/!", new LinkServlet(), null, null);
40 // httpService.registerFilter("/", rootFilter, null, null);
41 } catch (Exception e) {
42 throw new CmsException("Cannot register filters", e);
43 }
44 }
45
46 public void destroy() {
47 }
48
49 class LinkServlet extends HttpServlet {
50 private static final long serialVersionUID = 3749990143146845708L;
51
52 @Override
53 protected void service(HttpServletRequest request,
54 HttpServletResponse response) throws ServletException,
55 IOException {
56 String path = request.getPathInfo();
57 String userAgent = request.getHeader("User-Agent").toLowerCase();
58 boolean isBot = false;
59 boolean isCompatibleBrowser = false;
60 if (userAgent.contains("bot")) {
61 isBot = true;
62 } else if (userAgent.contains("webkit")
63 || userAgent.contains("gecko")
64 || userAgent.contains("firefox")
65 || userAgent.contains("msie")
66 || userAgent.contains("chrome")
67 || userAgent.contains("chromium")
68 || userAgent.contains("opera")
69 || userAgent.contains("browser")) {
70 isCompatibleBrowser = true;
71 }
72
73 if (isCompatibleBrowser) {// redirect
74 response.setHeader("Location", "/#" + path);
75 response.setStatus(HttpServletResponse.SC_FOUND);
76 } else {
77 if (isBot && log.isDebugEnabled())
78 log.debug(request.getHeader("User-Agent") + " is a bot");
79 // TODO pure html
80 throw new UnsupportedOperationException();
81 }
82 }
83 }
84
85 /** Intercepts all requests. Authenticates. */
86 class RootFilter extends HttpFilter {
87
88 @Override
89 public void doFilter(HttpSession httpSession,
90 HttpServletRequest request, HttpServletResponse response,
91 FilterChain filterChain) throws IOException, ServletException {
92 if (log.isTraceEnabled()) {
93 log.trace(request.getRequestURL().append(
94 request.getQueryString() != null ? "?"
95 + request.getQueryString() : ""));
96 logRequest(request);
97 }
98
99 String servletPath = request.getServletPath();
100
101 // client certificate
102 X509Certificate clientCert = extractCertificate(request);
103 if (clientCert != null) {
104 // TODO authenticate
105 // if (log.isDebugEnabled())
106 // log.debug(clientCert.getSubjectX500Principal().getName());
107 }
108
109 // skip data
110 if (servletPath.startsWith(PATH_DATA)) {
111 filterChain.doFilter(request, response);
112 return;
113 }
114
115 // skip /ui (workbench) for the time being
116 if (servletPath.startsWith(PATH_WORKBENCH)) {
117 filterChain.doFilter(request, response);
118 return;
119 }
120
121 // redirect long RWT paths to anchor
122 String path = request.getRequestURI().substring(
123 servletPath.length());
124 int pathLength = path.length();
125 if (pathLength != 0 && (path.charAt(0) == '/')
126 && !servletPath.endsWith("rwt-resources")
127 && !path.startsWith(KernelConstants.PATH_WORKBENCH)
128 && path.lastIndexOf('/') != 0) {
129 String newLocation = request.getServletPath() + "#" + path;
130 response.setHeader("Location", newLocation);
131 response.setStatus(HttpServletResponse.SC_FOUND);
132 return;
133 }
134
135 // process normally
136 filterChain.doFilter(request, response);
137 }
138 }
139
140 private void logRequest(HttpServletRequest request) {
141 log.debug("contextPath=" + request.getContextPath());
142 log.debug("servletPath=" + request.getServletPath());
143 log.debug("requestURI=" + request.getRequestURI());
144 log.debug("queryString=" + request.getQueryString());
145 StringBuilder buf = new StringBuilder();
146 // headers
147 Enumeration<String> en = request.getHeaderNames();
148 while (en.hasMoreElements()) {
149 String header = en.nextElement();
150 Enumeration<String> values = request.getHeaders(header);
151 while (values.hasMoreElements())
152 buf.append(" " + header + ": " + values.nextElement());
153 buf.append('\n');
154 }
155
156 // attributed
157 Enumeration<String> an = request.getAttributeNames();
158 while (an.hasMoreElements()) {
159 String attr = an.nextElement();
160 Object value = request.getAttribute(attr);
161 buf.append(" " + attr + ": " + value);
162 buf.append('\n');
163 }
164 log.debug("\n" + buf);
165 }
166
167 private X509Certificate extractCertificate(HttpServletRequest req) {
168 X509Certificate[] certs = (X509Certificate[]) req
169 .getAttribute("javax.servlet.request.X509Certificate");
170 if (null != certs && certs.length > 0) {
171 return certs[0];
172 }
173 return null;
174 }
175
176 // class CustomDosFilter extends DoSFilter {
177 // @Override
178 // protected String extractUserId(ServletRequest request) {
179 // HttpSession httpSession = ((HttpServletRequest) request)
180 // .getSession();
181 // if (isSessionAuthenticated(httpSession)) {
182 // String userId = ((SecurityContext) httpSession
183 // .getAttribute(SPRING_SECURITY_CONTEXT_KEY))
184 // .getAuthentication().getName();
185 // return userId;
186 // }
187 // return super.extractUserId(request);
188 //
189 // }
190 // }
191 }