Shapira, Yoav wrote:
Hi, That's an interesting approach: I'm glad it works for you. You and others should carefully consider using this approach, however, if you have clients that may refuse to join in a session. Such clients do exist, and the HttpSession guidelines mandate that your servlet(s) be accommodating of them: "A servlet should be able to handle cases in which the client does not choose to join a session, such as when cookies are intentionally turned off. Until the client joins the session, isNew returns true. If the client chooses not to join the session, getSession will return a different session on each request, and isNew will always return true." (This is from the HttpSession JavaDoc).
So of course, when every getSession returns a different one, the flag attribute will never be set, and this approach fails. This is a corner case, and one you probably don't need to worry about, but it's good to keep in mind (and in the archives for this thread) for people who do care.
And with that, a good weekend to all ;)
Yoav Shapira Millennium Research Informatics
-----Original Message----- From: Harry Mantheakis [mailto:[EMAIL PROTECTED] Sent: Friday, June 11, 2004 3:54 PM To: Tomcat Users List Subject: Re: Denial Service Attack Prevention apache-tomcat modjk2
I've just come off implementing something very much like what Wade has recommended, and it works a treat.
Note the use of a finally block to release the session lock, which is
cool.
Basically, the first request sets a flag stored in the session object
so
that no other (subsequent) request will be processed for that session object.
The problem is that the response from the first request will never be received by the client, if the client manages to send another request before the first one has responded.
If the client sends another request whilst the first is still
processing,
the controller servlet redirects the request to come back to the server (and make a fresh request) in the expectation that the first request will
have
finished by the time the second request has re-bounded.
The server keeps a count of how many 'rebounds' are made, so that if
the
first request is taking a long time to process, the 3rd rebound is
passed
to a 'progress bar' JSP that is programmed to refresh itself at
increasingly
slower rates. (I use custom tags to programmatically set the refresh
rate.)
It is theoretically possible for the user to be left in limbo if
something
happens to permanently block the processing of the first request - but
that
is an unlikely event, so the risk is worthwhile.
The cool bit is that once the fist request has finished processing it
sets
a 'state' attribute (or set of attributes) in the session, so that any subsequent request (a rebound or a progress-bar JSP seeking to refresh itself) will get a response that is identical to what the first request would have generated.
That's kind of like a restaurant where the customer can never change
their
order. If they ask for a salad, that is it. No matter how long it takes
to
cook, and however many times they ask to change their order to chicken, they get a salad at the end!
This stuff can really do your head in when you first start thinking
about
it, but after while it gets easier.
Bottom line: session is you best friend. Use it.
Good luck!
Harry Mantheakis London, UK
Replying on top of Yoav's because I don't have the other message.
If it is a large enough operation your could do something like this:
//check if running String methodName = "com.mypackage.MyClass.myMethod"; //pull value from session test and add if needed. Boolean isRunning = (Boolean)session.getAttribute(methodName); if( isRunning != null && isRunning.booleanValue() ) { //hand off to other method that tells them to please wait. } else { //first let app know user is doing task. session.setAttribute(methodName, new Boolean(true));
//perform that large task try { //do work that might jump out here... } catch(Throwable e) {
} finally { //ok, it's done...remove from session. session.removeAttribute(methodName); } }//end else
Now the large task can't eat up your cpu more than you let it because
it
only runs once per user at a time. Sleeping the thread a little
after
so many iterations in loops also will help your entire server and application. After maybe every 1000 iterations sleep for a couple of millis. Play with that sometimes it helps sometimes not. It spreads
out
the load over time a bit and allows the computer to service more
users,
it just takes longer...
Hope that helps you some.
Wade
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
This e-mail, including any attachments, is a confidential business communication, and may contain information that is confidential, proprietary and/or privileged. This e-mail is intended only for the individual(s) to whom it is addressed, and may not be saved, copied, printed, disclosed or used by anyone else. If you are not the(an) intended recipient, please immediately delete this e-mail from your computer system and notify the sender. Thank you.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Yes when I posted the response he is speaking of I left that out and in the air. I assumed the forcing of cookies and sessions. I usually assume those things when very heavy work is occuring, but this is definitely something I should have mentioned.
Thanks Yoav.
Wade
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]