blob: 02854e94debcd3addde0e0dc77ff2318fd9c7d33 [file] [log] [blame]
/*
* 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.felix.http.itest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.osgi.framework.Constants.SERVICE_RANKING;
import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME;
import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH;
import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME;
import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.json.JsonObject;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.johnzon.core.JsonProviderImpl;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.context.ServletContextHelper;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
public class SessionHandlingTest extends BaseIntegrationTest
{
private List<ServiceRegistration<?>> registrations = new ArrayList<>();
private CountDownLatch initLatch;
private CountDownLatch destroyLatch;
private void setupLatches(int count)
{
initLatch = new CountDownLatch(count);
destroyLatch = new CountDownLatch(count);
}
private void setupServlet(final String name, String[] path, int rank, final String context) throws Exception
{
Dictionary<String, Object> servletProps = new Hashtable<>();
servletProps.put(HTTP_WHITEBOARD_SERVLET_NAME, name);
servletProps.put(HTTP_WHITEBOARD_SERVLET_PATTERN, path);
servletProps.put(SERVICE_RANKING, rank);
if (context != null)
{
servletProps.put(HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=" + context + ")");
}
Servlet sessionServlet = new TestServlet(initLatch, destroyLatch)
{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException
{
final boolean create = req.getParameter("create") != null;
if ( create )
{
req.getSession();
}
final boolean destroy = req.getParameter("destroy") != null;
if ( destroy )
{
req.getSession().invalidate();
}
final HttpSession s = req.getSession(false);
if ( s != null )
{
s.setAttribute("value", context);
}
final PrintWriter pw = resp.getWriter();
pw.println("{");
if ( s == null )
{
pw.println(" \"session\" : false");
}
else
{
pw.println(" \"session\" : true,");
pw.println(" \"sessionId\" : \"" + s.getId() + "\",");
pw.println(" \"value\" : \"" + s.getAttribute("value") + "\",");
pw.println(" \"hashCode\" : \"" + s.hashCode() + "\"");
}
pw.println("}");
}
};
registrations.add(m_context.registerService(Servlet.class.getName(), sessionServlet, servletProps));
}
private void setupContext(String name, String path) throws InterruptedException
{
Dictionary<String, ?> properties = createDictionary(
HTTP_WHITEBOARD_CONTEXT_NAME, name,
HTTP_WHITEBOARD_CONTEXT_PATH, path);
ServletContextHelper servletContextHelper = new ServletContextHelper(m_context.getBundle()){
// test helper
};
registrations.add(m_context.registerService(ServletContextHelper.class.getName(), servletContextHelper, properties));
Thread.sleep(500);
}
@After
public void unregisterServices() throws InterruptedException
{
for (ServiceRegistration<?> serviceRegistration : registrations)
{
serviceRegistration.unregister();
}
assertTrue(destroyLatch.await(5, TimeUnit.SECONDS));
Thread.sleep(500);
}
private JsonObject getJSONResponse(final CloseableHttpClient client, final String path) throws IOException
{
final HttpGet httpGet = new HttpGet(createURL(path).toExternalForm().toString());
CloseableHttpResponse response1 = client.execute(httpGet);
try {
HttpEntity entity1 = response1.getEntity();
final String content = EntityUtils.toString(entity1);
return new JsonProviderImpl().createReader(new StringReader(content)).readObject();
} finally {
response1.close();
}
}
@Test
public void testSessionAttributes() throws Exception
{
setupContext("test1", "/");
setupContext("test2", "/");
setupLatches(2);
setupServlet("foo", new String[] { "/foo" }, 1, "test1");
setupServlet("bar", new String[] { "/bar" }, 2, "test2" );
assertTrue(initLatch.await(5, TimeUnit.SECONDS));
RequestConfig globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.build();
final CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(globalConfig)
.setDefaultCookieStore(new BasicCookieStore())
.build();
JsonObject json;
// session should not be available
// check for foo servlet
json = getJSONResponse(httpclient, "/foo");
assertFalse(json.getBoolean("session"));
// check for bar servlet
json = getJSONResponse(httpclient, "/bar");
assertFalse(json.getBoolean("session"));
// create session for context of servlet foo
// check session and session attribute
json = getJSONResponse(httpclient, "/foo?create=true");
assertTrue(json.getBoolean("session"));
assertEquals("test1", json.getString("value"));
final String sessionId1 = json.getString("sessionId");
assertNotNull(sessionId1);
final String hashCode1 = json.getString("hashCode");
assertNotNull(hashCode1);
// check session for servlet bar (= no session)
json = getJSONResponse(httpclient, "/bar");
assertFalse(json.getBoolean("session"));
// another request to servlet foo, still the same
json = getJSONResponse(httpclient, "/foo");
assertTrue(json.getBoolean("session"));
assertEquals("test1", json.getString("value"));
assertEquals(sessionId1, json.getString("sessionId"));
// create session for second context
json = getJSONResponse(httpclient, "/bar?create=true");
assertTrue(json.getBoolean("session"));
assertEquals("test2", json.getString("value"));
final String sessionId2 = json.getString("sessionId");
assertNotNull(sessionId2);
final String hashCode2 = json.getString("hashCode");
assertNotNull(hashCode2);
assertFalse(hashCode2.equals(hashCode1));
// and context foo is untouched
json = getJSONResponse(httpclient, "/foo");
assertTrue(json.getBoolean("session"));
assertEquals("test1", json.getString("value"));
assertEquals(sessionId1, json.getString("sessionId"));
// invalidate session for foo context
json = getJSONResponse(httpclient, "/foo?destroy=true");
assertFalse(json.getBoolean("session"));
// bar should be untouched
json = getJSONResponse(httpclient, "/bar");
assertTrue(json.getBoolean("session"));
assertEquals("test2", json.getString("value"));
assertEquals(sessionId2, json.getString("sessionId"));
}
}