12 Replies Latest reply on May 21, 2014 9:55 AM by michpetrov

    File upload widget?

      Hey Michal, folks,

       

      have you already though about what widget to use for RF5 file upload?

       

      Something like those ones?

       

       

       

      Cheers,

       

      ~ Lukas

       

        • 1. Re: File upload widget?
          michpetrov

          I've been looking on the server side of things in RF5 and got kinda stuck there.

           

          I think the first one might be better since it is already a jQuery widget and the layout looks similar to what we're aiming for.

          • 2. Re: File upload widget?
            bleathem

            On Wed 12 Feb 2014 03:24:41 AM PST, Michal Petrov wrote:

             

            I've been looking on the server side of things in RF5 and got kinda

            stuck there.

             

            Be sure to reach out to Lukas or myself if you need a hand sorting out

            what's going on there.

             

            I think the first one might be better since it is already a jQuery

            widget and the layout looks similar to what we're aiming for.

             

            Looking at these options Lukas pointed out:

             

            Option 1) http://blueimp.github.io/jQuery-File-Upload/basic-plus.html

             

            Pros: MIT license, jQuery based, Bootstrap themed, simple/familiar UI

             

            Option 2)  http://www.dropzonejs.com/

             

            Pros: MIT license, Neat drag/drop UI

            Con: Seems limited to a drag/drop UI

             

            I agree with Micha;s assessment that Option 1) seems like a better fit.

             

            Is anyone familiar with any other file upload widgets we should consider?

             

            Brian

            _______________________________________________

            richfaces-dev mailing list

            richfaces-dev@lists.jboss.org

            https://lists.jboss.org/mailman/listinfo/richfaces-dev

             

            • 3. Re: File upload widget?

              ad) new widget

               

              we might want to do more rigorous search for alternative widgets.

               

              Let's collect requirements here:

               

              • drag-drop

              • progress indication

              • file size limits

              • rejection per file / mime-type

               

              (practically all things original widget had, just client-side)

               

              -


               

              ad) server-side implementation:

               

              good thing: client-side impl should completely avoid a need for heavyweight

              server-side impl

               

              bad thing: we won't be able to get rid of server-side impl /wrt processing

              in Servlets < 3.0 (such as 2.5).

               

              In fact, when we would limit ourselves to Servlets 3.0, the code is almost

              done (JSF 2.2 already implemented leverages it).

              But as JSF impls adopts most of the code for multipart/form-data request

              processing from Servlets 3.0, we can use the same path.

               

              ~ Lukas

               

               

              On Wed, Feb 12, 2014 at 12:24 PM, Michal Petrov <

              richfaces-dev@lists.jboss.org> wrote:

               

              I've been looking on the server side of things in RF5 and got kinda stuck

              there.

               

              I think the first one might be better since it is already a jQuery widget

              and the layout looks similar to what we're aiming for.

               

              Posted by forums

              Original post: https://community.jboss.org/message/857306#857306

              _______________________________________________

              richfaces-dev mailing list

              richfaces-dev@lists.jboss.org

              https://lists.jboss.org/mailman/listinfo/richfaces-dev

               

               

              • 4. Re: Re: File upload widget?
                michpetrov

                ad) new widget

                 

                we might want to do more rigorous search for alternative widgets.

                 

                Let's collect requirements here:

                 

                • drag-drop

                • progress indication

                • file size limits

                • rejection per file / mime-type

                 

                (practically all things original widget had, just client-side)

                I will take a look but those requirements do not seem hard to implement if we needed to. Drop support in particular is just a listener for drop event and can be easily added to the current fileUpload.

                 

                Concerning the server side what are the requirements past sending the files to a servlet, are we letting the user handle it?

                • 5. Re: Re: File upload widget?

                  We need to check all the criteria that file upload defines on both,

                  server-side and client-side.

                  Otherwise an "attacker" could bypass the criteria by modifying client-side

                  code.

                   

                   

                  On Thu, Feb 13, 2014 at 3:14 PM, Michal Petrov <

                  richfaces-dev@lists.jboss.org> wrote:

                   

                   

                  > ad) new widget

                  >

                  >

                  >

                  > we might want to do more rigorous search for alternative widgets.

                  >

                  >

                  >

                  > Let's collect requirements here:

                  >

                  >

                  >

                  >

                  > *

                  > drag-drop

                  >

                  >

                  > *

                  > progress indication

                  >

                  >

                  > *

                  > file size limits

                  >

                  >

                  > *

                  > rejection per file / mime-type

                  >

                  >

                  >

                  >

                  >

                  > (practically all things original widget had, just client-side)

                  >

                  I will take a look but those requirements do not seem hard to implement if

                  we needed to. Drop support in particular is just a listener for drop event

                  and can be easily added to the current fileUpload.

                   

                  Concerning the server side what are the requirements past sending the

                  files to a servlet, are we letting the user handle it?

                   

                  Posted by forums

                  Original post: https://community.jboss.org/message/857511#857511

                  _______________________________________________

                  richfaces-dev mailing list

                  richfaces-dev@lists.jboss.org

                  https://lists.jboss.org/mailman/listinfo/richfaces-dev

                   

                   

                  • 6. Re: Re: File upload widget?

                    As Michal mentioned on the team meeting, we are not able to hook into

                    XMLHttpRequest object that we need to make client-side progress tracking

                    work.

                     

                    We did a bit of research with Brian yesteday and found out that there is no

                    other library that would do what we want to achieve, so we can't really get

                    inspired elsewhere.

                     

                    Note: the only such implementation is PrimeFaces but they don't use

                    standard JSF AJAX (jsf.ajax.request function), they use jQuery.ajax

                     

                     

                     

                    If we look into implementation of jsf.js, XMLHttpRequest (XHR) is not

                    really exposed anywhere, not even on onevent('begin') .

                     

                    I believe it would be significant improvement to expose XHR instance used

                    to drive given JSF AJAX request here, that's why I will fill

                    JAVASERVERFACES (and MyFaces) issue

                     

                    Fortunately, there is a way how to hook into XHR instance itself - it is

                    possible to intercept XHR.open method by overriding its declaration.

                    That's also the approach that we use in Graphene (the impl there is

                    actually more powerful than we need here).

                     

                    Even though, Graphene implementation is proven to work cross-browser:

                    • IE8+ (IE7 and less is not worth the trouble)

                    • Firefox, Chrome, Safari

                    • Opera support unknown

                     

                     

                     

                     

                    The idea is that we can:

                     

                    1. override a XHR.open method just before jsf.ajax.request

                    2. wait for call to XHR.open and store reference to the invoked XHR instance

                    3. override a XHR.open method back just after jsf.ajax.request method

                     

                    These steps should be performed in a try {} catch {} block and if we do not

                    succeed to obtain XHR instance this way, we should perform fallback to show

                    progress bar that reflects "uploading" and "upload completed" states.

                     

                    There are two possible places for overriding:

                    1. richfaces.js intercepts calls to jsf.ajax.request already

                    2. in fileupload.js - note: I'm not sure whether we should do

                    submitForm here, we may use RichFaces.ajax / jsf.ajax.request

                     

                     

                    ~ Lukas

                     

                     

                    https://github.com/jboss/mohttp://stackoverflow.com/questions/629671/how-can-i-intercept-xmlhttprequests-from-a-greasemonkey-scriptjarra/blob/2.2.5-jbossorg-3/jsf-api/src/main/resources/jsf.js#L1958

                    http://stackoverflow.com/questions/629671/how-can-i-intercept-xmlhttprequests-from-a-greasemonkey-script

                    https://github.com/arquillian/arquillian-graphene/blob/master/impl/src/main/javascript/Graphene.xhrInterception.js

                    http://www.w3schools.com/browsers/browsers_explorer.asp

                    https://github.com/richfaces/richfaces/blob/master/framework/src/main/resources/META-INF/resources/org.richfaces/richfaces.js#L583

                    https://github.com/richfaces/richfaces/blob/master/framework/src/main/resources/META-INF/resources/org.richfaces/input/fileUpload/fileupload.js#L252

                     

                     

                    On Thu, Feb 13, 2014 at 3:55 PM, Lukáš Fryč <lukas.fryc@gmail.com> wrote:

                     

                    We need to check all the criteria that file upload defines on both,

                    server-side and client-side.

                    Otherwise an "attacker" could bypass the criteria by modifying client-side

                    code.

                     

                    >

                    On Thu, Feb 13, 2014 at 3:14 PM, Michal Petrov <

                    richfaces-dev@lists.jboss.org> wrote:

                     

                    >>

                     

                    >> ad) new widget

                    >>

                    >>

                    >>

                    >> we might want to do more rigorous search for alternative widgets.

                    >>

                    >>

                    >>

                    >> Let's collect requirements here:

                    >>

                    >>

                    >>

                    >>

                    >> *

                    >> drag-drop

                    >>

                    >>

                    >> *

                    >> progress indication

                    >>

                    >>

                    >> *

                    >> file size limits

                    >>

                    >>

                    >> *

                    >> rejection per file / mime-type

                    >>

                    >>

                    >>

                    >>

                    >>

                    >> (practically all things original widget had, just client-side)

                    >>

                    >> I will take a look but those requirements do not seem hard to implement

                    >> if we needed to. Drop support in particular is just a listener for drop

                    >> event and can be easily added to the current fileUpload.

                    >>

                    >> Concerning the server side what are the requirements past sending the

                    >> files to a servlet, are we letting the user handle it?

                    >>

                    >> Posted by forums

                    >> Original post: https://community.jboss.org/message/857511#857511

                    >> _______________________________________________

                    >> richfaces-dev mailing list

                    >> richfaces-dev@lists.jboss.org

                    >> https://lists.jboss.org/mailman/listinfo/richfaces-dev

                    >>

                    >

                     

                    • 7. Re: Re: File upload widget?
                      michpetrov

                      I've found another way around this.

                       

                      The issue is that by sending a custom XHR the ApplyRequestValues phase doesn't decode the fileUpload component (where server-side checking happens and FileUploadEvents are enqueued).

                       

                      The JSF documentation describes how to make a custom request and have it recognized on the server; I've implemented this in the current fileUpload. The progress events do not fire as expected but I think that's because I'm sending the request to the local server. As for the @render and @execute - do they need to happen after each file is uploaded or only after all the files are uploaded? I have to check but there might be an issue with values like @region.

                      • 8. Re: Re: Re: File upload widget?
                        michpetrov

                        As I mentioned on the meeting the fileUpload wasn't working for me, not even the current iframe-based version. As it turns out I can only get it to work on WildFly-8.0.0.CR1 (Mojarra 2.2.4-jbossorg-1), it doesn't work on WildFly 8 Final (Mojarra 2.2.5-jbossorg-3).

                         

                        What I found out is that when the form is submitted the necessary parameters are not sent with it, especially javax.faces.ViewState. When JSF doesn't find the viewState parameter it skips the Apply Request Values phase which is where we check the files and put the upload events in a queue. There might be something in JavaScript, but if it doesn't find even the parameters sent by the standard XHR (I'll have to check that) I guess there is a bug.

                        • 9. Re: Re: Re: Re: File upload widget?
                          michpetrov

                          Well, it's not a Mojarra issue. The issue is with Undertow (the web server used by WildFly).

                           

                          When the request is sent on server (HttpServletRequestImpl) we're wrapping it in MultiPartRequest30, after that the request parameters cannot be reached. But for some reason it is working if I access the parameters before the request is wrapped.

                           

                          from FileUploadFacesContextFactory:

                          if (httpRequest.getContentType() != null && httpRequest.getContentType().startsWith("multipart/")) {
                              String uid = getParameterValueFromQueryString(httpRequest.getQueryString(), UID_KEY);
                          
                              Enumeration<String> e = httpRequest.getParameterNames();
                              // without this line the parameters are inaccessible
                          
                              if (uid != null) {
                                  long contentLength = Long.parseLong(httpRequest.getHeader("Content-Length"));
                          
                                  …
                          
                                              
                                  HttpServletRequest wrappedRequest;
                                  if (ServletVersion.getCurrent().isCompliantWith(ServletVersion.SERVLET_3_0)) {
                                      wrappedRequest = wrapMultipartRequestServlet30((ServletContext) context, httpRequest, uid,
                                                       contentLength, progressControl);
                                  } else {
                                      wrappedRequest = wrapMultipartRequestServlet25((ServletContext) context, httpRequest,
                                                       uid, contentLength, progressControl);
                                  }
                          
                              /*
                          
                              wrappedRequest.getParameter("javax.faces.ViewState") 
                              returns null unless the getParameterNames() method was called
                          
                              */
                              }
                          }
                          
                          
                          

                           

                          I'm not yet sure about the root of the issue but there seems to be a check for files being sent in the request which is why it only seems to affect fileUpload (that and I don't think we're wrapping the requests anywhere else).

                           

                          Edit:

                           

                          Ok, found it. In MultiPartRequest we call getParts() to find the file, this will call HttpServletRequestImpl.loadParts() and that will set a flag (readStarted) to true. Now the parameter request - the parameter is not found in the queryString and so the request tries to parse the form data but that fails because the readStarted flag is true. (When the getParameterNames() is called readStarted is false and so the data is parsed successfully).

                          • 10. Re: File upload widget?
                            bleathem

                            On 14-03-07 08:29 AM, Michal Petrov wrote:

                            Well, it's not a Mojarra issue. The issue is with Undertow (http://undertow.io/) (the web server used by WildFly).

                             

                            Nice work in isolating this issue Michal.  Please go ahead and file an

                            UNDERTOW jira issue when you feel you have sufficient information to do so.

                             

                            Brian

                            _______________________________________________

                            richfaces-dev mailing list

                            richfaces-dev@lists.jboss.org

                            https://lists.jboss.org/mailman/listinfo/richfaces-dev

                             

                            • 11. Re: Re: Re: Re: Re: File upload widget?
                              michpetrov

                              I've ran into an issue regarding the servlet versions.

                               

                              With the update we're adding support for Servlet 3.0 which makes processing the requests easier. However while we can detect what version the server supports we can't detect the actual version that is used and we cannot treat 2.5 as 3.0. This isn't an issue on WildFly which uses Servlet 3.0 by default but for example EAP 6.1 uses 2.5 by default (even though it supports 3.0).

                               

                              We have two options - either configure the servlet for 3.0 in web.xml:

                              <servlet>
                                  <servlet-name>Faces Servlet</servlet-name>
                                  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
                                  <load-on-startup>1</load-on-startup>
                                  <multipart-config>
                                      <max-file-size>20848820</max-file-size>
                                      <max-request-size>418018841</max-request-size>
                                      <file-size-threshold>1048576</file-size-threshold>
                                  </multipart-config>
                              </servlet>
                              

                              so we'll have to update all projects that make use of fileUpload. (I have to check what's the minimal necessary configuration). Or find a way to properly determine what servlet version we're dealing with.

                              • 12. Re: File upload widget?
                                michpetrov

                                It would seem checking if request.getParts() is not empty is enough to determine the servlet version. One other issue was that servlet 2.5 cannot recognize the multipart/form-data encoding so all necessary parameters have to be put in the URL instead of being part of the FormData we're sending.