private String getOriginOrReferer(HttpServletRequest pReq) { String origin = pReq.getHeader("Origin"); if (origin == null) { origin = pReq.getHeader("Referer"); } return origin != null ? origin.replaceAll("[\\n\\r]*", "") : null; }
/** * OPTION requests are treated as CORS preflight requests * * @param req the original request * @param resp the response the answer are written to */ @Override protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Map<String, String> responseHeaders = requestHandler.handleCorsPreflightRequest( req.getHeader("Origin"), req.getHeader("Access-Control-Request-Headers")); for (Map.Entry<String, String> entry : responseHeaders.entrySet()) { resp.setHeader(entry.getKey(), entry.getValue()); } }
// Get parameter map either directly from an Servlet 2.4 compliant implementation // or by looking it up explictely (thanks to codewax for the patch) private Map<String, String[]> getParameterMap(HttpServletRequest pReq) { try { // Servlet 2.4 API return pReq.getParameterMap(); } catch (UnsupportedOperationException exp) { // Thrown by 'pseudo' 2.4 Servlet API implementations which fake a 2.4 API // As a service for the parameter map is build up explicitely Map<String, String[]> ret = new HashMap<String, String[]>(); Enumeration params = pReq.getParameterNames(); while (params.hasMoreElements()) { String param = (String) params.nextElement(); ret.put(param, pReq.getParameterValues(param)); } return ret; } }
// Extract mime type for response (if not JSONP) private String getMimeType(HttpServletRequest pReq) { String requestMimeType = pReq.getParameter(ConfigKey.MIME_TYPE.getKeyValue()); if (requestMimeType != null) { return requestMimeType; } return configMimeType; }
// Set an appropriate CORS header if requested and if allowed private void setCorsHeader(HttpServletRequest pReq, HttpServletResponse pResp) { String origin = requestHandler.extractCorsOrigin(pReq.getHeader("Origin")); if (origin != null) { pResp.setHeader("Access-Control-Allow-Origin", origin); pResp.setHeader("Access-Control-Allow-Credentials", "true"); } }
// Update the agent URL in the agent details if not already done private void updateAgentDetailsIfNeeded(HttpServletRequest pReq) { // Lookup the Agent URL if needed AgentDetails details = backendManager.getAgentDetails(); if (details.isInitRequired()) { synchronized (details) { if (details.isInitRequired()) { if (details.isUrlMissing()) { String url = getBaseUrl( NetworkUtil.sanitizeLocalUrl(pReq.getRequestURL().toString()), extractServletPath(pReq)); details.setUrl(url); } if (details.isSecuredMissing()) { details.setSecured(pReq.getAuthType() != null); } details.seal(); } } } }
@SuppressWarnings({"PMD.AvoidCatchingThrowable", "PMD.AvoidInstanceofChecksInCatchClause"}) private void handle( ServletRequestHandler pReqHandler, HttpServletRequest pReq, HttpServletResponse pResp) throws IOException { JSONAware json = null; try { // Check access policy requestHandler.checkAccess( pReq.getRemoteHost(), pReq.getRemoteAddr(), getOriginOrReferer(pReq)); // Remember the agent URL upon the first request. Needed for discovery updateAgentDetailsIfNeeded(pReq); // Dispatch for the proper HTTP request method json = handleSecurely(pReqHandler, pReq, pResp); } catch (Throwable exp) { json = requestHandler.handleThrowable( exp instanceof RuntimeMBeanException ? ((RuntimeMBeanException) exp).getTargetException() : exp); } finally { setCorsHeader(pReq, pResp); String callback = pReq.getParameter(ConfigKey.CALLBACK.getKeyValue()); String answer = json != null ? json.toJSONString() : requestHandler .handleThrowable(new Exception("Internal error while handling an exception")) .toJSONString(); if (callback != null) { // Send a JSONP response sendResponse(pResp, "text/javascript", callback + "(" + answer + ");"); } else { sendResponse(pResp, getMimeType(pReq), answer); } } }
private JSONAware handleSecurely( final ServletRequestHandler pReqHandler, final HttpServletRequest pReq, final HttpServletResponse pResp) throws IOException, PrivilegedActionException { Subject subject = (Subject) pReq.getAttribute(ConfigKey.JAAS_SUBJECT_REQUEST_ATTRIBUTE); if (subject != null) { return Subject.doAs( subject, new PrivilegedExceptionAction<JSONAware>() { public JSONAware run() throws IOException { return pReqHandler.handleRequest(pReq, pResp); } }); } else { return pReqHandler.handleRequest(pReq, pResp); } }
private String extractServletPath(HttpServletRequest pReq) { return pReq.getRequestURI().substring(0, pReq.getContextPath().length()); }