Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jetty-users] Understanding AsyncMiddleManServlet request lifecycle

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?


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.

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"?

Thanks again, sorry for the rapid-fire questions, but there is precious little documentation on more advanced uses of this proxy servlet :)

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail


Back to the top