[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [jetty-users] Understanding AsyncMiddleManServlet request lifecycle
|
Hi,
On Fri, Nov 3, 2017 at 11:56 PM, Steven Schlansker
<stevenschlansker@xxxxxxxxx> wrote:
> I'm trying to extend the Requests created by my Awesome Jetty Based Proxy 2.0 to include company specific metadata.
>
> I instrument it before sending it off to the base impl:
>
> @Override
> public void service(HttpServletRequest req, HttpServletResponse resp) {
> final ProxyContext ctx = new ProxyContext(req, resp, ...);
> request.setAttribute(PROXY_CONTEXT, ctx);
> LOG.debug("context instrumented '{}': {}", ServletUtil.uriIncludingQueryString(request), request);
> super.service(req, resp);
> }
>
>
> @Override
> protected void onProxyResponseSuccess(HttpServletRequest clientRequest, HttpServletResponse proxyResponse, Response serverResponse) {
> super.onProxyResponseSuccess(clientRequest, proxyResponse, serverResponse);
> if (clientRequest.getAttribute(PROXY_CONTEXT) == null) {
> LOG.debug("No proxy context on {}", ToStringBuilder.reflectionToString(clientRequest));
> }
> }
>
> This code leads to:
>
> DEBUG [default-pool-22] c.o.f.p.AwesomeJettyProxy20 - context instrumented '...': Request(GET //XXX/...)@b8d137b
> DEBUG [default-pool-44] c.o.f.p.AwesomeJettyProxy20 - No proxy context on org.eclipse.jetty.server.Request@b8d137b[_channel=HttpChannelOverHttp@42d3f47d{r=12,c=false,a=IDLE,uri=null},_requestAttributeListeners=[],_input=HttpInputOverHTTP@4c140257[c=0,q=0,[0]=null,s=STREAM],_metaData=<null>,_originalURI=<null>,_contextPath=<null>,_servletPath=<null>,_pathInfo=<null>,_secure=false,_asyncNotSupportedSource=<null>,_newContext=false,_cookiesExtracted=false,_handled=false,_contentParamsExtracted=false,_requestedSessionIdFromCookie=false,_attributes={},_authentication=NOT CHECKED,_characterEncoding=<null>,_context=<null>,_cookies=<null>,_dispatcherType=<null>,_inputState=0,_queryParameters=<null>,_contentParameters=<null>,_parameters=<null>,_queryEncoding=<null>,_reader=<null>,_readerEncoding=<null>,_remote=<null>,_requestedSessionId=<null>,_scope=<null>,_session=<null>,_sessionHandler=<null>,_timeStamp=0,_multiPartInputStream=<null>,_async=<null>]
>
> Note that the Request object has the same Object hashCode b8d137b as the initial one. However, all fields -- not just the attributes -- are observed to be null.
>
> It sure looks like the request object is getting recycled before the callback is being invoked. But that seems crazy! How am I to do anything with it if all fields are nulled out first?
You are mistakenly calling super.onProxyResponseSuccess(...) _before_
pulling out the PROXY_CONTEXT attribute.
Method onProxyResponseSuccess() is called when the server-to-proxy
response is successful, and what it does is to call
AsyncContext.complete() to complete the proxy-to-client response.
Just call super _after_ your logic.
> Relatedly, I am finding that not all my incoming requests exit via onClientRequestFailure / onProxyResponse{Failure,Success}. In particular I have an "in flight" count that is incremented on service() and decremented on each of those three callbacks -- and the number increases continually.
>
That is not expected, but please make it work properly and try again.
If you see the same behavior, then it's something we want to investigate.
> It's possible this is related to the loss of attributes. But assuming I get that figured out, is it expected that *all* requests that begin will exit through one of these three paths? If not, is there a callback I can register that will get called when the request ends, no matter what failure it encounters? Maybe Expect: 100-continue adds some confusion here as well, will there be multiple "exits" for a single "entry"?
>
Those 3 should be all the failure paths. 100-continue should not matter.
--
Simone Bordet
----
http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.