[undertow-dev] FormDataProcessor ending exchange prematurely

Bill O'Neil bill at dartalley.com
Tue Feb 7 11:11:31 EST 2017


Hey Sven,

What kind of sanitization are you looking for? It should be handling form
encoding for you but I don't think any other type of sanitization.

On Tue, Feb 7, 2017 at 10:17 AM, Sven Kubiak <sven at kubiak.me> wrote:

> ​​​Anyone?
>
>
> Cheers,
>
> Sven
>
>
> ------------------------------
> *Von:* Sven Kubiak
> *Gesendet:* Mittwoch, 25. Januar 2017 15:58
> *An:* Bill O'Neil; Stuart Douglas
> *Cc:* Oliver Dain; undertow-dev at lists.jboss.org
> *Betreff:* AW: [undertow-dev] FormDataProcessor ending exchange
> prematurely
>
>
> Hi,
>
>
> sorry, for a kind of off-topic question, but as the FormDataProcessor is
> the topic here, I was wondering if there is already some kind of data
> sanitization​ in the core form handling of Undertow. If not, which handler
> is a good starting point to hook into for this?
>
>
> Best regards,
>
> Sven
>
>
> ------------------------------
> *Von:* undertow-dev-bounces at lists.jboss.org <undertow-dev-bounces at lists.
> jboss.org> im Auftrag von Bill O'Neil <bill at dartalley.com>
> *Gesendet:* Mittwoch, 25. Januar 2017 14:53
> *An:* Stuart Douglas
> *Cc:* Oliver Dain; undertow-dev at lists.jboss.org
> *Betreff:* Re: [undertow-dev] FormDataProcessor ending exchange
> prematurely
>
> Hey Stuart, your last response reminded me of of a question I had
> hopefully its not unrelated. I was curious how and when you should dispatch
> back to the IO thread. For example lets say we have a simple handler that
> does a SQL query that is composed with the AccessLogHandler.
>
> AccessLogHandler -> BlockingHandler -> CustomSqlHandler In this approach I
> believe the final access log statement will be logged from the worker
> thread not the initial IO thread.
>
> Is it possible / recommended to kick back to an IO thread once blocking is
> complete?
>
> AccessLogHandler -> BlockingHandler -> CustomSqlHandler ->
> DispatchBackToIOThread? This way the final logging of AccessLogHandler is
> handled in the IO thread.
>
> I'm not very familiar with the best ways to mix the nonblocking and
> blocking handlers.
>
>
>
> On Wed, Jan 25, 2017 at 12:24 AM, Stuart Douglas <sdouglas at redhat.com>
> wrote:
>
>> The handler is executed
>> io.undertow.server.Connectors#executeRootHandler, which means that
>> when the call stack returns the exchange will be ended.
>>
>> Conceptually this is similar to how dispatching to a thread pool
>> works, when you call dispatch(HttpHandler) the exchange will be ended
>> when the call stack returns, even though you are no longer on the IO
>> thread (unless you call dispatch again).
>>
>> Stuart
>>
>>
>> On Wed, Jan 25, 2017 at 3:57 PM, Oliver Dain <oliver at analyticspot.com>
>> wrote:
>> > I have some code for handling file uploads. It uses FormDataProcessor
>> and
>> > tries to do everything asynchronously. I call "FormDataParser.parse"
>> passing
>> > in another handler. I'll call that handler the OnFormDataAvailable. The
>> > OnFormDataAvailable handler checks to see if it's on the IO thread. If
>> it
>> > is, it calls dispatch. Either way, once we're sure we're dispatched that
>> > handler calls yet another handler.
>> >
>> > What I've seen is that my OnFormDataAvailable handler (the one called by
>> > parse()) is not on the IO thread so it doesn't need to call dispatch.
>> And
>> > yet, the exchange gets ended before the handler it calls is even close
>> to
>> > complete.
>> >
>> > I've found a fix, but I don't understand why it's necessary.
>> Specifically,
>> > if OnFormDataAvailable is not on the IO thread when its invoked it
>> calls the
>> > 0-argument version of "HttpServerExchange.dispatch()" (which you've
>> told me
>> > in another conversation shouldn't ever be necessary). If I do that,
>> > everything is fine.
>> >
>> > For completeness, here's the complete code:
>> >
>> > public class FormDataParsingHandler {
>> >   private static final Logger log =
>> > LoggerFactory.getLogger(FormDataParsingHandler.class);
>> >   private static final FormParserFactory formParserFactory =
>> > FormParserFactory.builder().build();
>> >   public static final AttachmentKey<FormData> FORM_DATA_ATTACHMENT_KEY =
>> > AttachmentKey.create(FormData.class);
>> >
>> >   /**
>> >    * The only public method - this is what gets exposed as the
>> HttpHandler.
>> >    */
>> >   public CompletableFuture<FormData> parseForm(HttpServerExchange
>> exchange)
>> > {
>> >     log.info("audio file upload request received.");
>> >     FormDataParser parser = formParserFactory.createParser(exchange);
>> >     if (parser == null) {
>> >       log.warn("No parser found that can handle this content type.
>> Headers
>> > were: {}", exchange.getRequestHeaders());
>> >       throw new UserVisibleException("No parser for the given content
>> > type.", ResponseCodes.BAD_REQUEST);
>> >     }
>> >
>> >     CompletableFuture<FormData> toComplete = new CompletableFuture<>();
>> >     try {
>> >       parser.parse(new OnFormDataAvailable(toComplete));
>> >     } catch (Exception e) {
>> >       log.error("Error parsing form data:", e);
>> >       throw wrapAsUnchecked(e);
>> >     }
>> >
>> >     exchange.addExchangeCompleteListener((ex, nextListener) -> {
>> >       // Must close the parser so it can free any temporary files that
>> were
>> > created.
>> >       try {
>> >         parser.close();
>> >       } catch (IOException e) {
>> >         log.error("Error closing the FormDataParser. Request was handled
>> > successfully but temporary files may not "
>> >             + "have been cleaned up.", e);
>> >       }
>> >       nextListener.proceed();
>> >     });
>> >
>> >     return toComplete;
>> >   }
>> >
>> >   // The FormDataParser calls an HttpHandler when it's complete so we
>> add a
>> > silly handler here that does nothing but
>> >   // complete this method's future when the form data is available.
>> >   private static class OnFormDataAvailable implements HttpHandler {
>> >     private final CompletableFuture<FormData> toComplete;
>> >
>> >     private OnFormDataAvailable(CompletableFuture<FormData>
>> toComplete) {
>> >       this.toComplete = toComplete;
>> >     }
>> >
>> >     @Override
>> >     public void handleRequest(HttpServerExchange exchange) throws
>> Exception
>> > {
>> >       // Before we complete the future we have to re-dispatch or we'll
>> fall
>> > off the end of this method and Undertow
>> >       // will complete the exchange on our behalf.
>> >       FormData data = exchange.getAttachment(FormDataParser.FORM_DATA);
>> >       if (exchange.isInIoThread()) {
>> >         log.debug("Was on the IO thread. Re-dispatching.");
>> >         exchange.dispatch(SameThreadExecutor.INSTANCE, () ->
>> > afterDistpach(data));
>> >       } else {
>> >         // THIS THE MYSTERY LINE. WHY IS THIS NEEDED?
>> >         exchange.dispatch();
>> >         afterDistpach(data);
>> >       }
>> >     }
>> >
>> >     private void afterDistpach(FormData data) {
>> >       if (data == null) {
>> >         toComplete.completeExceptionally(
>> >             new UserVisibleException("Parsing of data failed.",
>> > ResponseCodes.BAD_REQUEST));
>> >       } else {
>> >         toComplete.complete(data);
>> >       }
>> >     }
>> >   }
>> > }
>> >
>> > --
>> > CTO, Analytic Spot
>> > 44 West Broadway #222
>> > Eugene, OR 97401
>> > analyticspot.com • 425-296-6556
>> > www.linkedin.com/in/oliverdain
>> >
>> > _______________________________________________
>> > undertow-dev mailing list
>> > undertow-dev at lists.jboss.org
>> > https://lists.jboss.org/mailman/listinfo/undertow-dev
>>
>> _______________________________________________
>> undertow-dev mailing list
>> undertow-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/undertow-dev
>
>
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/undertow-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20170207/40d2e481/attachment.html 


More information about the undertow-dev mailing list