5 Replies Latest reply on Sep 27, 2010 10:11 PM by Minh Hoang TO

    DownloadHandler can't download file > 1M in GateIn?

    Hieu Ha Newbie

      I am deverloping a portlet that can upload and download file from JCR in GateIn portal. I use the DownloadHandler to download file like "http://localhost:8080/portal/command?type=org.exoplatform.web.command.handler.DownloadHandler&resourceId=17400981" and I found a bug in DownloadHandler. The file from JCR is small than 1MB it can run download, but if file is bigger than 1MB it camentn't download. I don't know why.

      My portlet run on GateIn-3.0.0-FINAL-jbossas and I made a new repository "orderform" to store my files.

       

      This is list of my file, it is too big to attach

      http://gioithieuwebsite.com/hieuhn/OrderForm-0.0.1-SNAPSHOT.ear

      http://gioithieuwebsite.com/hieuhn/repository-configuration.xml

      http://gioithieuwebsite.com/hieuhn/OrderForm_src.zip

       

      Could someone can help me this problem?

       

      Thanks,

      HieuHN

        • 1. Re: DownloadHandler can't download file > 1M in GateIn?
          Imre Hajagos Newbie

          Hello,

           

          There is a limit setting for eXo upload component in the reference guide:

          http://docs.jboss.com/gatein/portal/3.1.0-CR01/reference-guide/en-US/html_single/index.html#sect-Reference_Guide-Upload_Component

           

          That says you can set the parameter "upload.limit.size" to the component "org.exoplatform.upload.UploadService".

          I checked in the GateIn source code and I found this line in the constructor of the UploadService:

           

          defaultUploadLimitMB_ = Integer.parseInt(params.getValueParam("upload.limit.size").getValue());

           

          I also checked the DownloadService and I find this part:

           

          int maxSize = Integer.parseInt(params.getValueParam("download.resource.cache.size").getValue());

          downloadResources_ = new Cache(maxSize);

           

          So I guess you can set the parameter "download.resource.cache.size" to the "org.exoplatform.download.DownloadService".

          I Hope it is help.

           

          Regards

          • 2. Re: DownloadHandler can't download file > 1M in GateIn?
            Hieu Ha Newbie

            I have to write DownloadHandlerExt.class and put into new file "exo.portal.webui.eXo-3.0.0-GA_ext.jar" for my problem. Curently It run ok, but I don't think this is good solution.

            This is my code

             

            package org.exoplatform.web.command.handler;
            
            import org.exoplatform.container.ExoContainer;
            import org.exoplatform.container.ExoContainerContext;
            import org.exoplatform.download.DownloadResource;
            import org.exoplatform.download.DownloadService;
            import org.exoplatform.services.jcr.RepositoryService;
            import org.exoplatform.services.jcr.core.ManageableRepository;
            import org.exoplatform.services.jcr.ext.common.SessionProvider;
            import org.exoplatform.web.WebAppController;
            import org.exoplatform.web.command.Command;
            
            import java.io.IOException;
            import java.io.InputStream;
            import java.io.OutputStream;
            import java.net.URLDecoder;
            import java.net.URLEncoder;
            
            import javax.jcr.Node;
            import javax.jcr.Session;
            import javax.servlet.ServletOutputStream;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            public class DownloadHandlerExt extends Command
            {
            
               private String resourceId;
               private static final String REPOSITORY_NAME = "repository";
               private static final String WORK_SPACE_NAME = "orderform";
               /** JCR_DATA */
               private static final String JCR_DATA = "jcr:data";
            
               /** JCR_MIME_TYPE */
               private static final String JCR_MIME_TYPE = "jcr:mimeType";
            
               /** NT_RESOURCE */
               private static final String NT_RESOURCE = "nt:resource";
            
               /** JCR_CONTENT */
               private static final String JCR_CONTENT = "jcr:content";
            
               /** NT_FILE */
               private static final String NT_FILE = "nt:file";
            
            
               @SuppressWarnings("unused")
               public void execute(WebAppController controller, HttpServletRequest req, HttpServletResponse res) throws Exception
               {
                  res.setHeader("Cache-Control", "private max-age=6000, s-maxage=1200");
                  System.out.println("-----Start resourceId: " + resourceId);
                  resourceId = URLDecoder.decode(resourceId,"UTF-8");
                  if(resourceId.startsWith("%2F") || resourceId.startsWith("/")){
                      ExoContainer container = ExoContainerContext.getCurrentContainer();
                      RepositoryService repositoryService = (RepositoryService) container.getComponentInstanceOfType(RepositoryService.class);
                      ManageableRepository repository = repositoryService.getRepository(REPOSITORY_NAME);
                      SessionProvider provider = SessionProvider.createSystemProvider();
                      Session jcrSession = provider.getSession(WORK_SPACE_NAME, repository);
                      System.out.println("-----Start JCR process: " + resourceId);
                      if(jcrSession != null){
                          //Node documentNode = (Node) jcrSession.getItem(URLDecoder.decode(resourceId,"UTF-8"));
                          Node documentNode = (Node) jcrSession.getItem(resourceId);
                          System.out.println("-----resourceId decode: " + URLDecoder.decode(resourceId,"UTF-8"));
                          if(documentNode != null && NT_FILE.equals(documentNode.getPrimaryNodeType().getName())){
                              System.out.println("-----getName: " + documentNode.getName());
                              String userAgent = req.getHeader("User-Agent");
                              if (userAgent != null && userAgent.contains("MSIE"))
                              {
                                 res.setHeader("Content-Disposition", "attachment;filename=\""
                                    + URLEncoder.encode(documentNode.getName(),"UTF-8") + "\"");//documentNode.getName()
                                 System.out.println("----------Header---------- ");
                              }
                              else
                              {
                                  res.setHeader("Content-Disposition", "attachment; filename*=utf-8''"
                                      + URLEncoder.encode(documentNode.getName(), "UTF-8") + "");
                                 System.out.println("----------Header utf-8 ----------");
                              }
                              Node node4 = documentNode.getNode(JCR_CONTENT);
                              if(node4 != null && NT_RESOURCE.equals(node4.getPrimaryNodeType().getName())){
                                  res.setContentType(node4.getProperty(JCR_MIME_TYPE).getString());
                                  InputStream stream = node4.getProperty(JCR_DATA).getStream() ;
                                  ServletOutputStream out = res.getOutputStream();
                                  if (stream != null) {
                                      try {
                                          System.out.println("----------copy---------- ");
                                          copy(stream, out);
                                      } finally {
                                          stream.close();
                                      }
                                  }
                              }
                          }      
                      }
                      else{//document is NULL
                          res.setContentType("text/plain");
                          res.getWriter().write("NO JCR DOWNDLOAD RESOURCE CONTENT  OR YOU DO NOT HAVE THE RIGHT TO ACCESS THE CONTENT");
                          return;
                      }
                  }else{
                      ExoContainer container = ExoContainerContext.getCurrentContainer();
                      DownloadService dservice = (DownloadService)container.getComponentInstanceOfType(DownloadService.class);
                      DownloadResource dresource = dservice.getDownloadResource(resourceId);
                      if (dresource == null)
                      {
                         res.setContentType("text/plain");
                         res.getWriter().write("NO DOWNDLOAD RESOURCE CONTENT  OR YOU DO NOT HAVE THE RIGHT TO ACCESS THE CONTENT");
                         return;
                      }
                      String userAgent = req.getHeader("User-Agent");
                      if (dresource.getDownloadName() != null)
                      {
                         if (userAgent != null && userAgent.contains("MSIE"))
                         {
                            res.setHeader("Content-Disposition", "attachment;filename=\""
                               + URLEncoder.encode(dresource.getDownloadName(), "UTF-8") + "\"");
                         }
                         else
                         {
                            res.setHeader("Content-Disposition", "attachment; filename*=utf-8''"
                               + URLEncoder.encode(dresource.getDownloadName(), "UTF-8") + "");
                         }
                      }
                      res.setContentType(dresource.getResourceMimeType());
                      InputStream is = dresource.getInputStream();
                      try
                      {
                          optimalRead(is, res.getOutputStream());
                      }
                      catch (Exception ex)
                      {
                         ex.printStackTrace();
                      }
                      finally
                      {
                         is.close();
                      }
                  }
               }
            
               public String getResourceId()
               {
                  return resourceId;
               }
            
               private static void optimalRead(InputStream is, OutputStream os) throws Exception
               {
                  int bufferLength = 1024; //TODO: Better to compute bufferLength in term of -Xms, -Xmx properties
                  int readLength = 0;
                  while (readLength > -1)
                  {
                     byte[] chunk = new byte[bufferLength];
                     readLength = is.read(chunk);
                     if (readLength > 0)
                     {
                        os.write(chunk, 0, readLength);
                     }
                  }
               }
               private void copy(InputStream in, OutputStream out) throws IOException {
                   byte[] buffer = new byte[2048];
                   int read;
                   
                   while ((read = in.read(buffer)) != -1) {
                       out.write(buffer, 0, read);
                   }
               }
            }
            • 3. Re: DownloadHandler can't download file > 1M in GateIn?
              Khoi Nguyen Novice

              Hi Hieu

              I've written a portlet storing resource in JCR node, and download them, but no problem with a file >1M

              • 4. Re: DownloadHandler can't download file > 1M in GateIn?
                Khoi Nguyen Novice

                In your code, you shouldn't close the stream after getDownloadLink. This stream would be closed by DownloadService as soon as resource downloaded

                • 5. Re: DownloadHandler can't download file > 1M in GateIn?
                  Minh Hoang TO Novice

                  The exception IOException : Bad file descriptor   occurs when there is attempt to read an already closed InputStream