Injecting own ServletContextHandler in jetty server context

424 views
Skip to first unread message

Anton Moiseev

unread,
Jan 20, 2015, 6:13:19 AM1/20/15
to unfilter...@googlegroups.com
Hello, I am trying to work with sessions inside my web application, running on jetty. As far as I understand, working with sessions is implemented on the underlaying servlet container layer and not present in unfiltered API.

So I try to call

req.underlying.getSession.getId

and receive

java.lang.IllegalStateException: No SessionManager
    at org
.eclipse.jetty.server.Request.getSession(Request.java:1269)
    at org
.eclipse.jetty.server.Request.getSession(Request.java:1248)


I have found that exaclty same exception is described in this thread ("IllegalStateException: No SessionManager" thrown when using FormAuthenticator): https://bugs.eclipse.org/bugs/show_bug.cgi?id=403369

And it is related to Jetty, not to Unfiltered.

The fix is just to create ServletContextHandler in the following way (in Java):

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);

and then use it with Jetty server with something like:

Server server = new Server();
server
.setHandler(context);
or
server
.setHandler(context.getServletHandler());


I can see that inside Unfiltered ServletContextHandler is created in DefaultServletContextAdder:
https://github.com/unfiltered/unfiltered/blob/0.8.4/jetty/src/main/scala/contexts.scala#L25-L29

 def addToParent(parent: ContextHandlerCollection) = {
   val ctx
= new ServletContextHandler(parent, path, false, false)
   val holder
= new ServletHolder(classOf[org.eclipse.jetty.servlet.DefaultServlet])
   holder
.setName(CountedName.Servlet.name)
   ctx
.addServlet(holder, "/")

Which is then instantiated in Server.context:

https://github.com/unfiltered/unfiltered/blob/0.8.4/jetty/src/main/scala/Server.scala#L61-L65
 /** Add a servlet context with the given path */
 
def context(path: String)(block: ContextAdder => ContextAdder) = copy(
   contextAdders
=
     block
(DefaultServletContextAdder(path, Nil, None)) :: contextAdders)


So as far as I see, I must somehow replace DefaultServletContextAdder with my own implementation (probably
inherit and override addToParent with simple change) and somehow inject it to Server.context,
but I don't feel like I understand everything with this Scala constructions.

Have a feeling that this could be done somewhere here, probably:

unfiltered.jetty.Server.http(8080).context("/") {
     xxx
 
}.plan(JSecurityCheck).plan(handlePath).run()


thank's




Anton Moiseev

unread,
Jan 20, 2015, 9:25:39 AM1/20/15
to unfilter...@googlegroups.com
Ok, I have temporarily solved this for myself - added unfiltered-jetty project source code to my project source and changed single line in contexts.scala:

   val ctx = new ServletContextHandler(parent, path, false, false)

to

   val ctx = new ServletContextHandler(parent, path, true, false)

This is setting
ServletContextHandler constructor parameter sessions to true

http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/servlet/ServletContextHandler.html
ServletContextHandler(HandlerContainer parent, String contextPath, boolean sessions, boolean security)




Now I have sessions working with jetty like:

println("session id:" + req.underlying.getSession.getId)

session id:1v6stys8pjmdqfjm3vxtzfohr

Session id is required for form-based authentication which I am curretly trying to implement with Unfiltered.

I think this would still be nice to be able to set this option without adding library source code to project. Probably this could be added as additional config option to unfiltered-jetty api or maybe this parameter could be changed from false to true by default?
Reply all
Reply to author
Forward
0 new messages