<div dir="ltr">Genius idea.  In all my tests I hadn&#39;t thought of setting the response code in the predicate and then letting it continue to the servlet and caching it there.  I just tested this and it does appear to work well.<div><br></div><div>I added this outer handler chain wrapper to my deployment info</div><div><br><font face="monospace">        deploymentInfo.addOuterHandlerChainWrapper(next -&gt; new HttpHandler() {<br>            @Override<br>            public void handleRequest(HttpServerExchange exchange) throws Exception {<br>                if( exchange.getStatusCode() &gt; 399 &amp;&amp; exchange.getResponseContentLength() == -1 ) {<br>                    ServletRequestContext src = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);<br>                    ((HttpServletResponse)src.getServletResponse()).sendError(exchange.getStatusCode());<br>                } else {<br>                    next.handleRequest(exchange);<br>                }<br>            }<br>        });</font><br></div><div><br></div><div>(I don&#39;t know if the <font face="monospace">exchange.getResponseContentLength()</font> check is needed or the best way to do that)</div><div><br></div><div>And then I registered a custom handler I called <b>send-error-page</b> that has this handleRequest method:</div><div><br><font face="monospace">    public void handleRequest(final HttpServerExchange exchange) throws Exception {<br>        exchange.setStatusCode(responseCode);<br>        next.handleRequest(exchange);<br>    }</font><br></div><div><br></div><div>Then this predicate rule</div><div><br></div><div><font face="monospace">path(/box.json)-&gt;send-error-page(404)</font><br></div><div><br></div><div>serves up my servlet&#39;s custom error page for that request.</div><div><br></div><div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div></div><div>Thanks!</div><div><br></div><div>~Brad</div><div><br></div><div><b>Developer Advocate</b></div><div><i>Ortus Solutions, Corp </i></div><div><b><br></b></div><div>E-mail: <a href="mailto:brad@coldbox.org" target="_blank">brad@coldbox.org</a></div><div>ColdBox Platform: <a href="http://www.coldbox.org" target="_blank">http://www.coldbox.org</a> </div><div>Blog: <a href="http://www.codersrevolution.com" target="_blank">http://www.codersrevolution.com</a></div><div><br></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 7, 2020 at 6:39 PM Stuart Douglas &lt;<a href="mailto:sdouglas@redhat.com">sdouglas@redhat.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Basically I think the only way you can solve this is to attach the error code to the exchange somehow, then have a handler that reads the error code and calls sendError later.Basically write a new response-code handler that sets the code then calls the next handler (so the request gets to Servlet), then add a handler to the Servlet deployment that calls sendError if the exchange status code is &gt; 400.<br></div><div><br></div><div>We could actually add this to Undertow very simply, just add a &#39;continue&#39; param to the response code handler, then always call sendError in servlet if the incoming request response is &gt;400.</div><div><br></div><div>Can you try this out, and if it works I can look at getting it into Undertow.<br></div><div><br></div><div>Stuart<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 8 Jul 2020 at 02:35, Brad Wood &lt;<a href="mailto:bdw429s@gmail.com" target="_blank">bdw429s@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Stuart, any further suggestions or answers to my outstanding questions? So far, everything you&#39;ve suggested doesn&#39;t work for various reasons I&#39;ve shared here.  I also have a number of outstanding questions such as how I could access the deployment information for the servlet&#39;s error pages from inside an HTTPHandler running in the initial handler chain that fires in the XNIO worker.  <div><br clear="all"><div><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div></div><div>Thanks!</div><div><br></div><div>~Brad</div><div><br></div><div><b>Developer Advocate</b></div><div><i>Ortus Solutions, Corp </i></div><div><b><br></b></div><div>E-mail: <a href="mailto:brad@coldbox.org" target="_blank">brad@coldbox.org</a></div><div>ColdBox Platform: <a href="http://www.coldbox.org" target="_blank">http://www.coldbox.org</a> </div><div>Blog: <a href="http://www.codersrevolution.com" target="_blank">http://www.codersrevolution.com</a></div><div><br></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 3, 2020 at 3:55 PM Brad Wood &lt;<a href="mailto:bdw429s@gmail.com" target="_blank">bdw429s@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">After a few hours of experimenting, I was able to answer a few of my own questions, but not all of them.<div><ul><li>Yes, it is possible to contribute a custom handler to the predicate language-- this is actually pretty sweet.  I didn&#39;t realize just how generic the parser was.</li><li>In order to get &quot;picked up&quot;, the builder class must be listed in the <b>META-INF/services/io.undertow.server.handlers.builder.HandlerBuilder</b> file</li><li>That custom handler suggested by Stuart in the previous message ONLY works if the predicate chain is wrapped &quot;inside&quot; the servlet initial handler. Otherwise, the servletcontext classes are missing.  This unfortunately, makes it a no-go for me to be able to use.</li></ul><div>The rest of my questions still stand however in so far as how I can accomplish what I need.</div><div><br></div><div>During my experiments today, I also played with the error-file handler, but it also is of no use.  Since the response-code handler ends the exchange, any error pages declared in the error file handler are never used! </div><div><br></div><div><font face="monospace">error-file( response-codes={404}, file=&quot;C:\sandbox\predicatetest\custom404.html&quot; )<br>path(&#39;/box.json&#39;) -&gt; response-code(404)</font><br></div><div><br></div><div>I even tried creating a custom handler that sets the status code but continues the exchange, but then that just serves the original file anyway, which causes the error-file handler to do nothing since the response stream is already started. </div></div><div><br clear="all"><div><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div></div><div>Thanks!</div><div><br></div><div>~Brad</div><div><br></div><div><b>Developer Advocate</b></div><div><i>Ortus Solutions, Corp </i></div><div><b><br></b></div><div>E-mail: <a href="mailto:brad@coldbox.org" target="_blank">brad@coldbox.org</a></div><div>ColdBox Platform: <a href="http://www.coldbox.org" target="_blank">http://www.coldbox.org</a> </div><div>Blog: <a href="http://www.codersrevolution.com" target="_blank">http://www.codersrevolution.com</a></div><div><br></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 3, 2020 at 12:02 PM Brad Wood &lt;<a href="mailto:bdw429s@gmail.com" target="_blank">bdw429s@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">You probably need to write a custom one that looks like this (plus the relevant predicate languge bits): </blockquote><div><br></div><div>Stuart, if I can branch the conversation here back to your idea of a custom handler for a bit...</div><div><br></div><div>I&#39;m still toying with this, and while the handleRequest() code you have makes perfect sense, I think I&#39;m missing a lot of context on how you were suggesting this would work.</div><div><ul><li>The code you put in your message-- were you suggesting that should be added to the Undertow core as a built in handler or just a custom class I would put in my project?</li><li>Would this handler require the predicates be processed downstream of the servlet initial handler in order to work?  Because if so, that appears to be a no-go since handlers like the rewrite only appear to work upstream of the servlet </li><li>Is it possible to register custom handlers of my own creation with the predicate language or were you suggesting a handler that could only be manually configured?  I&#39;m familiar with the handler builder pattern that the built in handlers use, but I&#39;m unclear on how builders get registered with the predicate handler parser.  </li><li>Actually, I just reviewed the code again now and I see the loadHandlerBuilders() method in the PredicatedhandlersParser class appears to be scanning the classpath for builders.  Interesting....  Does Undertow need to be loaded by the same class loader that loaded my custom handlers for this to work?  I&#39;m not super familiar with the ServiceLoader stuff</li><li>I&#39;m not against building a custom handler that I ship alongside Undertow that provides what I&#39;m looking for, but I&#39;m still interested in having the conversation of how we can improve undertow&#39;s core offering.</li></ul></div><div>Thanks!<br></div><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><br></div><div>~Brad</div><div><br></div><div><b>Developer Advocate</b></div><div><i>Ortus Solutions, Corp </i></div><div><b><br></b></div><div>E-mail: <a href="mailto:brad@coldbox.org" target="_blank">brad@coldbox.org</a></div><div>ColdBox Platform: <a href="http://www.coldbox.org" target="_blank">http://www.coldbox.org</a> </div><div>Blog: <a href="http://www.codersrevolution.com" target="_blank">http://www.codersrevolution.com</a></div><div><br></div></div></div></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 2, 2020 at 7:01 PM Stuart Douglas &lt;<a href="mailto:sdouglas@redhat.com" target="_blank">sdouglas@redhat.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hmm, this is because the servlet status code is only triggered by a sendError method, not by just setting the code.</div><div><br></div><div>You probably need to write a custom one that looks like this (plus the relevant predicate languge bits):</div><div><br></div><div>public class SendErrorHandler implements HttpHandler {<br>    <br>    private final int code;<br><br>    public SendErrorHandler(int code) {<br>        this.code = code;<br>    }<br><br>    @Override<br>    public void handleRequest(HttpServerExchange exchange) throws Exception {<br>        ServletRequestContext src = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);<br>        ((HttpServletResponse)src.getServletResponse()).sendError(code);<br>    }<br>}</div><div><br></div><div>Stuart<br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 3 Jul 2020 at 09:40, Brad Wood &lt;<a href="mailto:bdw429s@gmail.com" target="_blank">bdw429s@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks for the reply Stuart.  I&#39;ve tried this with no success, but perhaps I&#39;m doing it wrong.<div><br><font face="monospace" color="#0000ff">List&lt;PredicatedHandler&gt; ph = PredicatedHandlersParser.parse(predicatesLines, _classLoader);<br>servletBuilder.addOuterHandlerChainWrapper(next -&gt; Handlers.predicates(ph,next));</font><br></div><div><br></div><div>When the response-code handler fires, I still get no response body.</div><div><br></div><div>On a related note, when I move the predicates into an outer handler chain wrapper, my default response listener also doesn&#39;t fire at all.  </div><div><br></div><div>On an unrelated train of thought, I&#39;ve been trying to see if I can get the default response listener to automatically dispatch the correct error page, but that hasn&#39;t been going well either.  If I don&#39;t use the outer handler chain idea, but try to capture the empty response in a default response listener, I can return a static message using the Sender class</div><div><br></div><div><font face="monospace" color="#0000ff">Sender sender = exchange.getResponseSender();<br>sender.send(errorHTMLString);</font><br></div><div><br></div><div>But if I try to run something this in my default response listener to invoke my error pages</div><div><br></div><div><font face="monospace" color="#0000ff">ServletRequestContext src = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);<br>HttpServletResponseImpl response = src.getOriginalResponse();<br>response.doErrorDispatch( exchange.getStatusCode(), exchange.getReasonPhrase() );</font><br></div><div><br></div><div>Then it&#39;s as though nothing happens and I still get an empty response.</div><div><br clear="all"><div><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div></div><div>Thanks!</div><div><br></div><div>~Brad</div><div><br></div><div><b>Developer Advocate</b></div><div><i>Ortus Solutions, Corp </i></div><div><b><br></b></div><div>E-mail: <a href="mailto:brad@coldbox.org" target="_blank">brad@coldbox.org</a></div><div>ColdBox Platform: <a href="http://www.coldbox.org" target="_blank">http://www.coldbox.org</a> </div><div>Blog: <a href="http://www.codersrevolution.com" target="_blank">http://www.codersrevolution.com</a></div><div><br></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 2, 2020 at 6:17 PM Stuart Douglas &lt;<a href="mailto:sdouglas@redhat.com" target="_blank">sdouglas@redhat.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>The predicate languages are executed before the Servler handlers, so they won&#39;t be handled by Servlet error pages.</div><div><br></div><div>If you are setting this all up programmatically you could use io.undertow.servlet.api.DeploymentInfo#addOuterHandlerChainWrapper to setup the predicate handler after the initial servlet one, which should mean that the servlet error handling will handle the response code.</div><div><br></div><div>Stuart<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 3 Jul 2020 at 08:25, Brad Wood &lt;<a href="mailto:bdw429s@gmail.com" target="_blank">bdw429s@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">When I configure an error page similar to this:<div><br></div><div><font face="monospace" color="#0000ff">servletBuilder.addErrorPage( new ErrorPage( &quot;404.html&quot;, 404));</font><br></div><div><br></div><div>This works great when I hit a path in my browser that doesn&#39;t exist.  The contents of the <b>404.html</b> file is served with a response code of <b>404</b>.</div><div><br></div><div>However, if I also use the predicate language to define something like:</div><div><br></div><div><font face="monospace" color="#0000ff">path(/box.json)-&gt;response-code(404)</font><br></div><div><br></div><div>and then I hit <b>localhost/box.json</b> in my browser, I get a <b>404</b> status code but with no response body. </div><div><ul><li>The docs say the response-code handler ends the exchange, but should it still respect the error pages?<br></li><li>How can I modify my use of Undertow to respect the error pages when using the response-code handler?</li><li>I&#39;ve seen in the docs the ability to have a <b>addDefaultResponseListener()</b> but I&#39;m not sure if it is the correct solution for this, nor how I would access the error page configuration dynamically as to not need to duplicate my work.</li></ul></div><div><div><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div>Thanks!</div><div><br></div><div>~Brad</div><div><br></div><div><b>Developer Advocate</b></div><div><i>Ortus Solutions, Corp </i></div><div><b><br></b></div><div>E-mail: <a href="mailto:brad@coldbox.org" target="_blank">brad@coldbox.org</a></div><div>ColdBox Platform: <a href="http://www.coldbox.org" target="_blank">http://www.coldbox.org</a> </div><div>Blog: <a href="http://www.codersrevolution.com" target="_blank">http://www.codersrevolution.com</a></div><div><br></div></div></div></div></div></div></div></div>
_______________________________________________<br>
undertow-dev mailing list<br>
<a href="mailto:undertow-dev@lists.jboss.org" target="_blank">undertow-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/undertow-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/undertow-dev</a></blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>