init
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.apache.catalina.valves;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.SessionCookieConfig;
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.Valve;
|
||||
import org.apache.catalina.connector.Request;
|
||||
import org.apache.catalina.connector.Response;
|
||||
import org.apache.catalina.core.StandardPipeline;
|
||||
import org.easymock.EasyMock;
|
||||
import org.easymock.IMocksControl;
|
||||
|
||||
public class TestLoadBalancerDrainingValve {
|
||||
|
||||
static class MockResponse extends Response {
|
||||
private List<Cookie> cookies;
|
||||
@Override
|
||||
public boolean isCommitted() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void addCookie(Cookie cookie)
|
||||
{
|
||||
if(null == cookies)
|
||||
cookies = new ArrayList<>(1);
|
||||
cookies.add(cookie);
|
||||
}
|
||||
@Override
|
||||
public List<Cookie> getCookies() {
|
||||
return cookies;
|
||||
}
|
||||
}
|
||||
|
||||
static class CookieConfig implements SessionCookieConfig {
|
||||
|
||||
private String name;
|
||||
private String domain;
|
||||
private String path;
|
||||
private String comment;
|
||||
private boolean httpOnly;
|
||||
private boolean secure;
|
||||
private int maxAge;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
@Override
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
@Override
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
@Override
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
@Override
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
@Override
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
@Override
|
||||
public boolean isHttpOnly() {
|
||||
return httpOnly;
|
||||
}
|
||||
@Override
|
||||
public void setHttpOnly(boolean httpOnly) {
|
||||
this.httpOnly = httpOnly;
|
||||
}
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return secure;
|
||||
}
|
||||
@Override
|
||||
public void setSecure(boolean secure) {
|
||||
this.secure = secure;
|
||||
}
|
||||
@Override
|
||||
public int getMaxAge() {
|
||||
return maxAge;
|
||||
}
|
||||
@Override
|
||||
public void setMaxAge(int maxAge) {
|
||||
this.maxAge = maxAge;
|
||||
}
|
||||
}
|
||||
|
||||
// A Cookie subclass that knows how to compare itself to other Cookie objects
|
||||
static class MyCookie extends Cookie {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MyCookie(String name, String value) { super(name, value); }
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(!(o instanceof MyCookie)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MyCookie mc = (MyCookie)o;
|
||||
return mc.getName().equals(this.getName())
|
||||
&& mc.getPath().equals(this.getPath())
|
||||
&& mc.getValue().equals(this.getValue())
|
||||
&& mc.getMaxAge() == this.getMaxAge();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + getMaxAge();
|
||||
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
|
||||
result = prime * result + ((getPath() == null) ? 0 : getPath().hashCode());
|
||||
result = prime * result + ((getValue() == null) ? 0 : getValue().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cookie { name=" + getName() + ", value=" + getValue() + ", path=" + getPath() + ", maxAge=" + getMaxAge() + " }";
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalRequest() throws Exception {
|
||||
runValve("ACT", true, true, false, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisabledValidSession() throws Exception {
|
||||
runValve("DIS", true, true, false, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisabledInvalidSession() throws Exception {
|
||||
runValve("DIS", false, false, false, "foo=bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisabledInvalidSessionWithIgnore() throws Exception {
|
||||
runValve("DIS", false, true, true, "foo=bar");
|
||||
}
|
||||
|
||||
private void runValve(String jkActivation,
|
||||
boolean validSessionId,
|
||||
boolean expectInvokeNext,
|
||||
boolean enableIgnore,
|
||||
String queryString) throws Exception {
|
||||
IMocksControl control = EasyMock.createControl();
|
||||
ServletContext servletContext = control.createMock(ServletContext.class);
|
||||
Context ctx = control.createMock(Context.class);
|
||||
Request request = control.createMock(Request.class);
|
||||
Response response = control.createMock(Response.class);
|
||||
|
||||
String sessionCookieName = "JSESSIONID";
|
||||
String sessionId = "cafebabe";
|
||||
String requestURI = "/test/path";
|
||||
SessionCookieConfig cookieConfig = new CookieConfig();
|
||||
cookieConfig.setDomain("example.com");
|
||||
cookieConfig.setName(sessionCookieName);
|
||||
cookieConfig.setPath("/");
|
||||
|
||||
// Valve.init requires all of this stuff
|
||||
EasyMock.expect(ctx.getMBeanKeyProperties()).andStubReturn("");
|
||||
EasyMock.expect(ctx.getName()).andStubReturn("");
|
||||
EasyMock.expect(ctx.getPipeline()).andStubReturn(new StandardPipeline());
|
||||
EasyMock.expect(ctx.getDomain()).andStubReturn("foo");
|
||||
EasyMock.expect(ctx.getLogger()).andStubReturn(org.apache.juli.logging.LogFactory.getLog(LoadBalancerDrainingValve.class));
|
||||
EasyMock.expect(ctx.getServletContext()).andStubReturn(servletContext);
|
||||
|
||||
// Set up the actual test
|
||||
EasyMock.expect(request.getAttribute(LoadBalancerDrainingValve.ATTRIBUTE_KEY_JK_LB_ACTIVATION)).andStubReturn(jkActivation);
|
||||
EasyMock.expect(Boolean.valueOf(request.isRequestedSessionIdValid())).andStubReturn(Boolean.valueOf(validSessionId));
|
||||
|
||||
ArrayList<Cookie> cookies = new ArrayList<>();
|
||||
if(enableIgnore) {
|
||||
cookies.add(new Cookie("ignore", "true"));
|
||||
}
|
||||
|
||||
if(!validSessionId) {
|
||||
MyCookie cookie = new MyCookie(cookieConfig.getName(), sessionId);
|
||||
cookie.setPath(cookieConfig.getPath());
|
||||
cookie.setValue(sessionId);
|
||||
|
||||
cookies.add(cookie);
|
||||
|
||||
EasyMock.expect(request.getRequestedSessionId()).andStubReturn(sessionId);
|
||||
EasyMock.expect(request.getRequestURI()).andStubReturn(requestURI);
|
||||
EasyMock.expect(request.getCookies()).andStubReturn(cookies.toArray(new Cookie[cookies.size()]));
|
||||
EasyMock.expect(request.getContext()).andStubReturn(ctx);
|
||||
EasyMock.expect(ctx.getSessionCookieName()).andStubReturn(sessionCookieName);
|
||||
EasyMock.expect(servletContext.getSessionCookieConfig()).andStubReturn(cookieConfig);
|
||||
EasyMock.expect(request.getQueryString()).andStubReturn(queryString);
|
||||
EasyMock.expect(ctx.getSessionCookiePath()).andStubReturn("/");
|
||||
|
||||
if (!enableIgnore) {
|
||||
EasyMock.expect(Boolean.valueOf(ctx.getSessionCookiePathUsesTrailingSlash())).andStubReturn(Boolean.TRUE);
|
||||
EasyMock.expect(request.getQueryString()).andStubReturn(queryString);
|
||||
// Response will have cookie deleted
|
||||
MyCookie expectedCookie = new MyCookie(cookieConfig.getName(), "");
|
||||
expectedCookie.setPath(cookieConfig.getPath());
|
||||
expectedCookie.setMaxAge(0);
|
||||
|
||||
// These two lines just mean EasyMock.expect(response.addCookie) but for a void method
|
||||
response.addCookie(expectedCookie);
|
||||
EasyMock.expect(ctx.getSessionCookieName()).andReturn(sessionCookieName); // Indirect call
|
||||
String expectedRequestURI = requestURI;
|
||||
if(null != queryString)
|
||||
expectedRequestURI = expectedRequestURI + '?' + queryString;
|
||||
response.setHeader("Location", expectedRequestURI);
|
||||
response.setStatus(307);
|
||||
}
|
||||
}
|
||||
|
||||
Valve next = control.createMock(Valve.class);
|
||||
|
||||
if(expectInvokeNext) {
|
||||
// Expect the "next" Valve to fire
|
||||
// Next 2 lines are basically EasyMock.expect(next.invoke(req,res)) but for a void method
|
||||
next.invoke(request, response);
|
||||
EasyMock.expectLastCall();
|
||||
}
|
||||
|
||||
// Get set to actually test
|
||||
control.replay();
|
||||
|
||||
LoadBalancerDrainingValve valve = new LoadBalancerDrainingValve();
|
||||
valve.setContainer(ctx);
|
||||
valve.init();
|
||||
valve.setNext(next);
|
||||
valve.setIgnoreCookieName("ignore");
|
||||
valve.setIgnoreCookieValue("true");
|
||||
|
||||
valve.invoke(request, response);
|
||||
|
||||
control.verify();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user