/** * Handle an HTTP status code or Java exception by forwarding control to the location included in * the specified errorPage object. It is assumed that the caller has already recorded any request * attributes that are to be forwarded to this page. Return <code>true</code> if we successfully * utilized the specified error page location, or <code>false</code> if the default error report * should be rendered. * * @param request The request being processed * @param response The response being generated * @param errorPage The errorPage directive we are obeying */ private boolean custom(Request request, Response response, ErrorPage errorPage) { if (container.getLogger().isDebugEnabled()) container.getLogger().debug("Processing " + errorPage); try { // Forward control to the specified location ServletContext servletContext = request.getContext().getServletContext(); RequestDispatcher rd = servletContext.getRequestDispatcher(errorPage.getLocation()); if (response.isCommitted()) { // Response is committed - including the error page is the // best we can do rd.include(request.getRequest(), response.getResponse()); } else { // Reset the response (keeping the real error code and message) response.resetBuffer(true); response.setContentLength(-1); rd.forward(request.getRequest(), response.getResponse()); // If we forward, the response is suspended again response.setSuspended(false); } // Indicate that we have successfully processed this custom page return (true); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); // Report our failure to process this custom page container.getLogger().error("Exception Processing " + errorPage, t); return (false); } }
@Override public void lifecycleEvent(LifecycleEvent event) { if (Lifecycle.BEFORE_STOP_EVENT.equals(event.getType())) { // The container is getting stopped, close all current connections Iterator<Request> iterator = cometRequests.iterator(); while (iterator.hasNext()) { Request request = iterator.next(); // Remove the session tracking attribute as it isn't // serializable or required. HttpSession session = request.getSession(false); if (session != null) { session.removeAttribute(cometRequestsAttribute); } // Close the comet connection try { CometEventImpl cometEvent = request.getEvent(); cometEvent.setEventType(CometEvent.EventType.END); cometEvent.setEventSubType(CometEvent.EventSubType.WEBAPP_RELOAD); getNext().event(request, request.getResponse(), cometEvent); cometEvent.close(); } catch (Exception e) { container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); } } cometRequests.clear(); } }
public void invoke(Request request, Response response) throws IOException, ServletException { try { if (!alreadySetLogbackStatusManager) { alreadySetLogbackStatusManager = true; org.apache.catalina.Context tomcatContext = request.getContext(); if (tomcatContext != null) { ServletContext sc = tomcatContext.getServletContext(); if (sc != null) { sc.setAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY, getStatusManager()); } } } getNext().invoke(request, response); TomcatServerAdapter adapter = new TomcatServerAdapter(request, response); AccessEvent accessEvent = new AccessEvent(request, response, adapter); if (getFilterChainDecision(accessEvent) == FilterReply.DENY) { return; } // TODO better exception handling aai.appendLoopOnAppenders(accessEvent); } finally { request.removeAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY); } }
@Override public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException { Principal principal = request.getUserPrincipal(); if (principal != null) { log.info("User " + principal.getName() + " is already autenticated"); return true; } Realm realm = request.getContext().getRealm(); log.info("Authentication against " + realm.toString() + " realm: " + realm.getInfo()); principal = realm.authenticate("user1", "password1"); if (principal != null) { request.setUserPrincipal(principal); log.info("Authentication via custom valve authenticator"); response.addHeader("valve", testparam); log.info( "Valve " + TestAuthenticator.class.getName() + " was hit and adding header parameter 'authenticated' with value " + testparam); return true; } log.warn("Login via global valve authenticator wasn't successfull"); return false; }
public static void invokeRequest(Valve pipelineHead, Request request) throws ServletException, IOException { pipelineHead.invoke(request, request.getResponse()); // StandardHostValve calls request.getSession(false) on way out, so we will too request.getSession(false); request.recycle(); }
/** * Register requests for tracking, whenever needed. * * @param request The servlet request to be processed * @param response The servlet response to be created * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ @Override public void invoke(Request request, Response response) throws IOException, ServletException { // Perform the request getNext().invoke(request, response); if (request.isComet() && !response.isClosed()) { // Start tracking this connection, since this is a // begin event, and Comet mode is on HttpSession session = request.getSession(true); // Track the connection for webapp reload cometRequests.add(request); // Track the connection for session expiration synchronized (session) { Request[] requests = (Request[]) session.getAttribute(cometRequestsAttribute); if (requests == null) { requests = new Request[1]; requests[0] = request; session.setAttribute(cometRequestsAttribute, requests); } else { Request[] newRequests = new Request[requests.length + 1]; for (int i = 0; i < requests.length; i++) { newRequests[i] = requests[i]; } newRequests[requests.length] = request; session.setAttribute(cometRequestsAttribute, newRequests); } } } }
@Test public final void testRequestFinishedShouldBeInvokedForIgnoredResources() throws IOException, ServletException { when(_request.getRequestedSessionId()).thenReturn("foo"); when(_request.getRequestURI()).thenReturn("/pixel.gif"); _sessionTrackerValve.invoke(_request, _response); verify(_service).requestFinished(eq("foo"), anyString()); }
/** * Send Cluster Replication Request * * @param request current request * @param manager session manager * @param cluster replication cluster */ protected void sendSessionReplicationMessage( Request request, ClusterManager manager, CatalinaCluster cluster) { Session session = request.getSessionInternal(false); if (session != null) { String uri = request.getDecodedRequestURI(); // request without session change if (!isRequestWithoutSessionChange(uri)) { if (log.isDebugEnabled()) log.debug(sm.getString("ReplicationValve.invoke.uri", uri)); sendMessage(session, manager, cluster); } else if (doStatistics()) nrOfFilterRequests++; } }
private void bz51881(CometEvent event) throws IOException { String[] tomcatVersion = config.getServletContext().getServerInfo().substring(14).split("\\."); String minorVersion = tomcatVersion[2]; if (minorVersion.indexOf("-") != -1) { minorVersion = minorVersion.substring(0, minorVersion.indexOf("-")); if (Integer.valueOf(minorVersion) == 22) { minorVersion = "23"; } } if (Integer.valueOf(tomcatVersion[0]) == 7 && Integer.valueOf(minorVersion) < 23) { logger.info( "Patching Tomcat 7.0.22 and lower bz51881. Expect NPE inside CoyoteAdapter, just ignore them. Upgrade to 7.0.23"); try { RequestFacade request = RequestFacade.class.cast(event.getHttpServletRequest()); Field coyoteRequest = RequestFacade.class.getDeclaredField("request"); coyoteRequest.setAccessible(true); Request r = (Request) coyoteRequest.get(request); r.recycle(); Field mappingData = Request.class.getDeclaredField("mappingData"); mappingData.setAccessible(true); MappingData m = new MappingData(); m.context = null; mappingData.set(r, m); } catch (Throwable t) { logger.trace("Was unable to recycle internal Tomcat object"); } finally { try { event.close(); } catch (IllegalStateException e) { logger.trace("", e); } } try { ResponseFacade response = ResponseFacade.class.cast(event.getHttpServletResponse()); Field coyoteResponse = ResponseFacade.class.getDeclaredField("response"); coyoteResponse.setAccessible(true); Response r = (Response) coyoteResponse.get(response); r.recycle(); } catch (Throwable t) { logger.trace("Was unable to recycle internal Tomcat object"); } } else { event.close(); } }
public boolean parse(Request request, String authorization) { // Validate the authorization credentials format if (authorization == null) { return false; } Map<String, String> directives; try { directives = Authorization.parseAuthorizationDigest(new StringReader(authorization)); } catch (IOException e) { return false; } if (directives == null) { return false; } method = request.getMethod(); userName = directives.get("username"); realmName = directives.get("realm"); nonce = directives.get("nonce"); nc = directives.get("nc"); cnonce = directives.get("cnonce"); qop = directives.get("qop"); uri = directives.get("uri"); response = directives.get("response"); opaqueReceived = directives.get("opaque"); return true; }
/** * Generate a unique token. The token is generated according to the following pattern. NOnceToken * = Base64 ( MD5 ( client-IP ":" time-stamp ":" private-key ) ). * * @param request HTTP Servlet request */ protected String generateNonce(Request request) { long currentTime = System.currentTimeMillis(); synchronized (lastTimestampLock) { if (currentTime > lastTimestamp) { lastTimestamp = currentTime; } else { currentTime = ++lastTimestamp; } } String ipTimeKey = request.getRemoteAddr() + ":" + currentTime + ":" + getKey(); byte[] buffer = ConcurrentMessageDigest.digestMD5(ipTimeKey.getBytes(StandardCharsets.ISO_8859_1)); String nonce = currentTime + ":" + MD5Encoder.encode(buffer); NonceInfo info = new NonceInfo(currentTime, getNonceCountWindowSize()); synchronized (nonces) { nonces.put(nonce, info); } return nonce; }
public Object authorize(AbstractSecurityContext context) throws Exception { startAuthorization(context); HttpGraniteContext graniteContext = (HttpGraniteContext) GraniteManager.getCurrentInstance(); HttpServletRequest httpRequest = graniteContext.getRequest(); Request request = getRequest(httpRequest); Session session = request.getSessionInternal(); request.setAuthType(session.getAuthType()); request.setUserPrincipal(session.getPrincipal()); if (context.getDestination().isSecured()) { Principal principal = getPrincipal(httpRequest); if (principal == null) { if (httpRequest.getRequestedSessionId() != null) { HttpSession httpSession = httpRequest.getSession(false); if (httpSession == null || httpRequest.getRequestedSessionId().equals(httpSession.getId())) throw SecurityServiceException.newSessionExpiredException("Session expired"); } throw SecurityServiceException.newNotLoggedInException("User not logged in"); } Realm realm = getRealm(httpRequest); boolean accessDenied = true; for (String role : context.getDestination().getRoles()) { if (realm.hasRole(principal, role)) { accessDenied = false; break; } } if (accessDenied) throw SecurityServiceException.newAccessDeniedException("User not in required role"); } try { return endAuthorization(context); } catch (InvocationTargetException e) { for (Throwable t = e; t != null; t = t.getCause()) { // Don't create a dependency to javax.ejb in SecurityService... if (t instanceof SecurityException || "javax.ejb.EJBAccessException".equals(t.getClass().getName())) throw SecurityServiceException.newAccessDeniedException(t.getMessage()); } throw e; } }
@Test public final void testRequestUrlIgnorePatternIsUsedIfPrimaryMemcachedNodeIsOperational() throws IOException, ServletException { when(_memcachedNodesManager.isNodeAvailable(PRIMARY_NODE_IDENTIFIER)).thenReturn(true); when(_request.getRequestURI()).thenReturn("/pixel.gif"); _sessionTrackerValve.invoke(_request, _response); verify(_request).setNote(REQUEST_IGNORED, Boolean.TRUE); }
@Override public void addElement( StringBuilder buf, Date date, Request request, Response response, long time) { HttpSession session = null; if (request != null) { session = request.getSession(false); if (session != null) buf.append(wrap(session.getAttribute(attribute))); } }
@Test public final void testChangeSessionIdForRelocatedSession() throws IOException, ServletException { final String sessionId = "bar"; final String newSessionId = "newId"; when(_request.getNote(eq(RequestTrackingHostValve.SESSION_ID_CHANGED))) .thenReturn(Boolean.TRUE); when(_request.getRequestedSessionId()).thenReturn(sessionId); final Cookie cookie = new Cookie(_sessionTrackerValve.getSessionCookieName(), newSessionId); setupGetResponseSetCookieHeadersExpectations( _response, new String[] {generateCookieString(cookie)}); _sessionTrackerValve.invoke(_request, _response); verify(_service).backupSession(eq(newSessionId), eq(true), anyString()); }
@Test public final void testRequestUrlIgnorePatternIsSkippedIfPrimaryMemcachedNodeIsDown() throws IOException, ServletException { when(_memcachedNodesManager.isNodeAvailable(PRIMARY_NODE_IDENTIFIER)).thenReturn(false); when(_request.getRequestedSessionId()).thenReturn(SESSION_ID); _sessionTrackerValve.invoke(_request, _response); verify(_request).setNote(RequestTrackingHostValve.REQUEST_PROCESS, Boolean.TRUE); }
@Test public final void testBackupSessionNotInvokedWhenNoSessionIdPresent() throws IOException, ServletException { when(_request.getRequestedSessionId()).thenReturn(null); when(_response.getHeader(eq("Set-Cookie"))).thenReturn(null); _sessionTrackerValve.invoke(_request, _response); verify(_service, never()).backupSession(anyString(), anyBoolean(), anyString()); }
/** * Invoke the next Valve in the sequence. When the invoke returns, check the response state, and * output an error report is necessary. * * @param request The servlet request to be processed * @param response The servlet response to be created * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ @Override public void invoke(Request request, Response response) throws IOException, ServletException { // Perform the request getNext().invoke(request, response); if (response.isCommitted()) { return; } Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); if (request.isAsyncStarted() && response.getStatus() < 400 && throwable == null) { return; } if (throwable != null) { // The response is an error response.setError(); // Reset the response (if possible) try { response.reset(); } catch (IllegalStateException e) { // Ignore } response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } response.setSuspended(false); try { report(request, response, throwable); } catch (Throwable tt) { ExceptionUtils.handleThrowable(tt); } if (request.isAsyncStarted()) { request.getAsyncContext().complete(); } }
/** * /** When we do GET call for WSDL/WADL, we do not want to authenticate/throttle the request. * * <p>TODO check logic * * @param request * @param response * @param compositeValve * @param context */ private void handleWSDLGetRequest( Request request, Response response, CompositeValve compositeValve, String context) { if (request.getMethod().equals(Constants.Configuration.HTTP_METHOD_GET)) { // TODO:Need to get these paths from a config file. if (request.getRequestURI().matches(context + "/[^/]*/services")) { getNext().invoke(request, response, compositeValve); return; } Enumeration<String> params = request.getParameterNames(); String paramName = null; while (params.hasMoreElements()) { paramName = params.nextElement(); if (paramName.endsWith("wsdl") || paramName.endsWith("wadl")) { getNext().invoke(request, response, compositeValve); return; } } } }
/* (non-Javadoc) * @see org.apache.catalina.valves.ValveBase#invoke(org.apache.catalina.connector.Request, org.apache.catalina.connector.Response) */ public void invoke(Request request, Response response) throws IOException, ServletException { getNext().invoke(request, response); HttpServletRequest servletRequest = request.getRequest(); HttpSession session = servletRequest.getSession(false); if (session != null) { String ip = IpInfo.getClientAddress(servletRequest); session.setAttribute(ApplicationSession.LAST_ACCESSED_BY_IP, ip); } }
@Override public void addElement( StringBuilder buf, Date date, Request request, Response response, long time) { Cookie[] c = request.getCookies(); for (int i = 0; c != null && i < c.length; i++) { if (name.equals(c[i].getName())) { buf.append(wrap(c[i].getValue())); } } }
public void testGetSession() { String requestedSessionId = "REQUESTED_SESSION_ID"; Context context = Mockito.mock(Context.class); CassandraTemplate template = new TestCassandraTemplate(); template.setLogSessionsOnStartup(true); template.initialize(getClass().getClassLoader()); CassandraManager manager = new HectorCassandraManager(); manager.setCassandraTemplate(template); Mockito.when(context.getManager()).thenReturn(manager); Request request = new Request(); request.setContext(context); // fake cookie sent a value request.setRequestedSessionId(requestedSessionId); HttpSession session = request.getSession(); Assert.assertFalse(requestedSessionId.equals(session.getId())); }
/** * Log the interesting request parameters, invoke the next Valve in the sequence, and log the * interesting response parameters. * * @param request The servlet request to be processed * @param response The servlet response to be created * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ @Override public void invoke(Request request, Response response) throws IOException, ServletException { long totalstart = 0; // this happens before the request if (doStatistics()) { totalstart = System.currentTimeMillis(); } if (primaryIndicator) { createPrimaryIndicator(request); } Context context = request.getContext(); boolean isCrossContext = context != null && context instanceof StandardContext && ((StandardContext) context).getCrossContext(); try { if (isCrossContext) { if (log.isDebugEnabled()) log.debug(sm.getString("ReplicationValve.crossContext.add")); // FIXME add Pool of Arraylists crossContextSessions.set(new ArrayList<DeltaSession>()); } getNext().invoke(request, response); if (context != null) { Manager manager = context.getManager(); if (manager != null && manager instanceof ClusterManager) { ClusterManager clusterManager = (ClusterManager) manager; CatalinaCluster containerCluster = (CatalinaCluster) getContainer().getCluster(); if (containerCluster == null) { if (log.isWarnEnabled()) log.warn(sm.getString("ReplicationValve.nocluster")); return; } // valve cluster can access manager - other cluster handle replication // at host level - hopefully! if (containerCluster.getManager(clusterManager.getName()) == null) return; if (containerCluster.hasMembers()) { sendReplicationMessage( request, totalstart, isCrossContext, clusterManager, containerCluster); } else { resetReplicationRequest(request, isCrossContext); } } } } finally { // Array must be remove: Current master request send endAccess at recycle. // Don't register this request session again! if (isCrossContext) { if (log.isDebugEnabled()) log.debug(sm.getString("ReplicationValve.crossContext.remove")); // crossContextSessions.remove() only exist at Java 5 // register ArrayList at a pool crossContextSessions.set(null); } } }
public String mygetHeader(Request request, String header) { String strcert0 = request.getHeader(header); if (strcert0 == null) { return null; } /* mod_header writes "(null)" when the ssl variable is no filled */ if ("(null)".equals(strcert0)) { return null; } return strcert0; }
protected void configureSessionCookie(Cookie cookie) { super.configureSessionCookie(cookie); String host = getServerName(); String domain = _getDomain(host); if (domain != null) { cookie.setDomain(domain); } }
@Test public final void testBackupSessionInvokedWhenResponseCookiePresent() throws IOException, ServletException { when(_request.getRequestedSessionId()).thenReturn(null); final Cookie cookie = new Cookie(_sessionTrackerValve.getSessionCookieName(), "foo"); setupGetResponseSetCookieHeadersExpectations( _response, new String[] {generateCookieString(cookie)}); _sessionTrackerValve.invoke(_request, _response); verify(_service).backupSession(eq("foo"), eq(false), anyString()); }
public void login(Object credentials) throws SecurityServiceException { String[] decoded = decodeBase64Credentials(credentials); HttpGraniteContext context = (HttpGraniteContext) GraniteManager.getCurrentInstance(); HttpServletRequest httpRequest = context.getRequest(); Realm realm = getRealm(httpRequest); Principal principal = realm.authenticate(decoded[0], decoded[1]); if (principal == null) throw SecurityServiceException.newInvalidCredentialsException("Wrong username or password"); Request request = getRequest(httpRequest); request.setAuthType(AUTH_TYPE); request.setUserPrincipal(principal); Session session = request.getSessionInternal(); session.setAuthType(AUTH_TYPE); session.setPrincipal(principal); session.setNote(Constants.SESS_USERNAME_NOTE, decoded[0]); session.setNote(Constants.SESS_PASSWORD_NOTE, decoded[1]); }
@Override public void invoke(Request request, Response response) throws IOException, ServletException { CometEventImpl event = new CometEventImpl(request, response); getNext().invoke(request, response); if (request.isComet()) { Thread t = new AsyncCometCloseThread(event); t.start(); } }
/** * Handle the HTTP status code (and corresponding message) generated while processing the * specified Request to produce the specified Response. Any exceptions that occur during * generation of the error report are logged and swallowed. * * @param request The request being processed * @param response The response being generated */ private void status(Request request, Response response) { int statusCode = response.getStatus(); // Handle a custom error page for this status code Context context = request.getContext(); if (context == null) return; /* Only look for error pages when isError() is set. * isError() is set when response.sendError() is invoked. This * allows custom error pages without relying on default from * web.xml. */ if (!response.isError()) return; ErrorPage errorPage = context.findErrorPage(statusCode); if (errorPage == null) { // Look for a default error page errorPage = context.findErrorPage(0); } if (errorPage != null && response.setErrorReported()) { response.setAppCommitted(false); request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, Integer.valueOf(statusCode)); String message = response.getMessage(); if (message == null) message = ""; request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); request.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, errorPage.getLocation()); request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ERROR); Wrapper wrapper = request.getWrapper(); if (wrapper != null) request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME, wrapper.getName()); request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); if (custom(request, response, errorPage)) { try { response.finishResponse(); } catch (ClientAbortException e) { // Ignore } catch (IOException e) { container.getLogger().warn("Exception Processing " + errorPage, e); } } } }
public boolean checkCorsPreflight(Request request, Response response) { log.finer("checkCorsPreflight " + request.getRequestURI()); if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { log.finer("checkCorsPreflight: not options "); return false; } if (request.getHeader("Origin") == null) { log.finer("checkCorsPreflight: no origin header"); return false; } log.finer("Preflight request returning"); response.setStatus(HttpServletResponse.SC_OK); String origin = request.getHeader("Origin"); response.setHeader("Access-Control-Allow-Origin", origin); response.setHeader("Access-Control-Allow-Credentials", "true"); String requestMethods = request.getHeader("Access-Control-Request-Method"); if (requestMethods != null) { if (deployment.getCorsAllowedMethods() != null) { requestMethods = deployment.getCorsAllowedMethods(); } response.setHeader("Access-Control-Allow-Methods", requestMethods); } String allowHeaders = request.getHeader("Access-Control-Request-Headers"); if (allowHeaders != null) { if (deployment.getCorsAllowedHeaders() != null) { allowHeaders = deployment.getCorsAllowedHeaders(); } response.setHeader("Access-Control-Allow-Headers", allowHeaders); } if (deployment.getCorsMaxAge() > -1) { response.setHeader("Access-Control-Max-Age", Integer.toString(deployment.getCorsMaxAge())); } return true; }