Package com.adito.vfs.webdav.methods

Source Code of com.adito.vfs.webdav.methods.GET

/* ========================================================================== *
* Copyright (C) 2004-2005 Pier Fumagalli <http://www.betaversion.org/~pier/> *
*                            All rights reserved.                            *
* ========================================================================== *
*                                                                            *
* Licensed under the  Apache License, Version 2.0  (the "License").  You may *
* not use this file except in compliance with the License.  You may obtain a *
* copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>.       *
*                                                                            *
* Unless  required  by applicable  law or  agreed  to  in writing,  software *
* distributed under the License is distributed on an  "AS IS" BASIS, WITHOUT *
* WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied.  See the *
* License for the  specific language  governing permissions  and limitations *
* under the License.                                                         *
*                                                                            *
* ========================================================================== */
package com.adito.vfs.webdav.methods;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.RandomAccessContent;
import org.apache.commons.vfs.util.RandomAccessMode;

import com.adito.boot.SystemProperties;
import com.adito.boot.Util;
import com.adito.vfs.VFSLockManager;
import com.adito.vfs.VFSResource;
import com.adito.vfs.webdav.DAVTransaction;
import com.adito.vfs.webdav.LockedException;

/**
* <p>
* <a href="http://www.rfc-editor.org/rfc/rfc2616.txt">HTTP</a>
* <code>GET</code> metohd implementation.
* </p>
*
* @author <a href="/">Pier Fumagalli</a>
*/
public class GET extends HEAD {

  static Log log = LogFactory.getLog(GET.class);
 
    /**
     * <p>
     * The mime type this method will return for collections.
     * </p>
     */
    public static final String COLLECTION_MIME_TYPE = "text/html";

    /**
     * <p>
     * Create a new {@link GET} instance.
     * </p>
     */
    public GET() {
        super();
    }

    /**
     * <p>
     * Process the <code>GET</code> method.
     * </p>
     */
    public void process(DAVTransaction transaction, VFSResource resource) throws LockedException, IOException {
       
     
      String handle = VFSLockManager.getNewHandle();
      VFSLockManager.getInstance().lock(resource, transaction.getSessionInfo(), false, true, handle);
     
      try {
        doHead(transaction, resource);
 
          try {
              if (resource.isCollection() || resource.isMount()) {
               
                if(SystemProperties.get("adito.disableFolderBrowsing", "true").equals("true") && !resource.isBrowsable()) {
                  transaction.getResponse().sendError(404);
                  return;
                }
               
                  String mime = COLLECTION_MIME_TYPE + "; charset=\"utf-8\"";
                  transaction.setContentType(mime);
 
                  Util.noCache(transaction.getResponse());
                 
                  PrintWriter out = transaction.write("utf-8");
                  String path = resource.getFullPath();
                  out.println("<html>");
                  out.println("<head>");
                  out.println("<title>Collection: " + path + "</title>");
                  out.println("</head>");
                  out.println("<body>");
                  out.println("<h2>Collection: " + path + "</h2>");
                  out.println("<table>");
                  out.println("<thead>");
                  out.println("<tr>");
                  out.println("<td>Name</td>");
                  out.println("<td>Type</td>");
                  out.println("<td>Size</td>");
                  out.println("<td>Date</td>");
                  out.println("</tr>");
                  out.println("</thead>");
                  out.println("<tbody>");
 
                  /* Process the parent */
                  VFSResource parent = resource.getParent();
                  if (parent != null && (parent.isBrowsable() || !SystemProperties.get("adito.disableFolderBrowsing", "true").equals("true"))) {
                    out.println("<tr>");
                      out.print("<td><li><a href=\"..\">../</a></td>");
                    out.println("<td>Dir</td><td>");
                    try {
                      out.println(parent.getFile().getContent().getSize());
                    }
                    catch(Exception e) {                     
                    }
                    out.println("</td><td>");
                    try {
                      out.println(SimpleDateFormat.getDateTimeInstance().format(new Date(parent.getFile().getContent().getLastModifiedTime())));
                    }
                    catch(Exception e) {                     
                    }
                    out.println("</td></tr>");
                  }
 
                  /* Process the children */
                  Iterator iterator = resource.getChildren();
                  if (iterator != null) {
                      while (iterator.hasNext()) {
                          VFSResource child = (VFSResource) iterator.next();
                          String childPath = child.getDisplayName();

                      out.println("<tr>");
                        out.print("<td><li><a href=\"" + child.getWebFolderPath() + "\">"  + childPath +  "</a></td>");
                        if(child.isCollection())
                          out.println("<td>Dir</td><td>");
                        else if(child.isResource())
                          out.println("<td>Resource</td><td>");
                        else
                          out.println("<td>Unknown</td><td>");
                      try {
                        out.println(child.getFile().getContent().getSize());
                      }
                      catch(Exception e) {                     
                      }
                      out.println("</td><td>");
                      try {
                        out.println(SimpleDateFormat.getDateTimeInstance().format(new Date(child.getFile().getContent().getLastModifiedTime())));
                      }
                      catch(Exception e) {                     
                      }
                      out.println("</td></tr>");
                      out.println("</tr>");
                      }
                  } 
                  out.println("</tbody>");
                  out.println("</table>");
                  out.println("</html>");
                  out.flush();
              if(resource.getMount() != null) {
                resource.getMount().resourceAccessList(resource, transaction, null);
              }
                  return;
              }
          } catch (Exception e) {
            if(resource.getMount() != null) {
              resource.getMount().resourceAccessList(resource, transaction, e);
            }
              IOException ioe = new IOException(e.getMessage());
              ioe.initCause(e);
              throw ioe;
          }
 
          int total = 0;
          try {
 
            Range[] ranges = null;
           
            try {
              ranges = processRangeHeader(transaction, resource);
            } catch(IOException ex) {
              // Invalid range means send full entity with 200 OK.
              ranges = null;
            }
           
              transaction.setHeader("Content-Type", resource.getContentType());

                resource.getMount().resourceAccessDownloading(resource, transaction);
 
              OutputStream out = transaction.getOutputStream();
              byte buffer[] = new byte[32768];

              InputStream in = null;
             
              try {
             
                if(ranges == null || ranges.length > 1 /* We dont support multiple ranges yet */) {
                  /* Processing a normal resource request */
                  in = resource.getInputStream();
                  int k;
                  while ((k = in.read(buffer)) != -1) {
                      out.write(buffer, 0, k);
                      total += k;
                  }
                } else {
                  /* Process a single range */
                 
                  RandomAccessContent content = resource.getFile().getContent().getRandomAccessContent(RandomAccessMode.READ);
   
                  content.seek(ranges[0].startPosition);
                  in = content.getInputStream();
               
                  long count = ranges[0].count;
                  int k;
                  while(count > 0) {
                      while ((k = in.read(buffer, 0, (int) (count < buffer.length ? count : buffer.length))) > 0) {
                          out.write(buffer, 0, k);
                          total += k;
                          count -= k;
                      }
                  }
                   
                  transaction.setHeader("Content-Range", "bytes " + ranges[0].startPosition
                      + "-" + ranges[0].startPosition
                      + ranges[0].count + "/" + resource.getFile().getContent().getSize());
                 
                  transaction.setStatus(206 /* Partial */);
                 
                }
              }
              finally {
                Util.closeStream(in);
              }
                resource.getMount().resourceAccessDownloadComplete(resource, transaction, null);
          } catch (IOException ioe) {
                resource.getMount().resourceAccessDownloadComplete(resource, transaction, ioe);
              throw ioe;
          }
        } finally {
          VFSLockManager.getInstance().unlock(transaction.getSessionInfo(), handle);
        }

    }
   
    private Range[] processRangeHeader(DAVTransaction transaction, VFSResource resource) throws IOException {
     
      try {
      if(transaction.getRequest().getHeader("Range")!=null) {
       
        String header = transaction.getRequest().getHeader("Range").toLowerCase();
       
        if(header.startsWith("bytes=")) {
         
          Vector v = new Vector();
         
          StringTokenizer tokens = new StringTokenizer(header.substring(6), ",");
          while(tokens.hasMoreTokens()) {
            String r = tokens.nextToken();

            if(log.isDebugEnabled())
              log.debug("Processing byte range " + r);
           
            int idx = r.indexOf('-');
           
            String startPoint = r.substring(0, idx);
            String endPoint = r.substring(idx+1);
           
            Range newRange = new Range();
           
            if("".equals(startPoint) && !"".equals(endPoint)) {
             
              newRange.count = Long.parseLong(endPoint);
              newRange.startPosition = resource.getFile().getContent().getSize() - newRange.count;
              v.add(newRange);
             
            } else if(!"".equals(startPoint) && "".equals(endPoint)) {
             
              newRange.startPosition = Long.parseLong(startPoint);
              newRange.count = resource.getFile().getContent().getSize() - newRange.startPosition;
                            v.add(newRange);
             
            } else if(!"".equals(startPoint) && !"".equals(endPoint)) {
             
              newRange.startPosition = Long.parseLong(startPoint);
              newRange.count = Long.parseLong(endPoint) - newRange.startPosition;
                            v.add(newRange);
             
            } else {
              log.error("Unsupported byte range element: " + r);
            }
          }
         
          if(v.size() > 0) {
            return (Range[]) v.toArray(new Range[0]);
          }
        }
       
      }
    } catch (Throwable t) {
      log.error("Failed to process byte range header " + transaction.getRequest().getHeader("Range"), t);
      throw new IOException("Invalid range");
    }
     
      return null;
    }
   
   
    class Range {
     
      long startPosition;
      long count;
    }
}
TOP

Related Classes of com.adito.vfs.webdav.methods.GET

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.