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(a)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(a)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(a)lists.jboss.org <undertow-dev-bounces@lists.
jboss.org> im Auftrag von Bill O'Neil <bill(a)dartalley.com>
*Gesendet:* Mittwoch, 25. Januar 2017 14:53
*An:* Stuart Douglas
*Cc:* Oliver Dain; undertow-dev(a)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(a)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(a)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(a)lists.jboss.org
> >
https://lists.jboss.org/mailman/listinfo/undertow-dev
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/undertow-dev
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev