1 17 package com.sslexplorer.vfs.webdav.methods; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 import java.io.PrintWriter ; 23 import java.text.SimpleDateFormat ; 24 import java.util.Date ; 25 import java.util.Iterator ; 26 import java.util.StringTokenizer ; 27 import java.util.Vector ; 28 29 import org.apache.commons.logging.Log; 30 import org.apache.commons.logging.LogFactory; 31 import org.apache.commons.vfs.RandomAccessContent; 32 import org.apache.commons.vfs.util.RandomAccessMode; 33 34 import com.sslexplorer.boot.Util; 35 import com.sslexplorer.vfs.VFSInputStream; 36 import com.sslexplorer.vfs.VFSLockManager; 37 import com.sslexplorer.vfs.VFSResource; 38 import com.sslexplorer.vfs.webdav.DAVTransaction; 39 import com.sslexplorer.vfs.webdav.LockedException; 40 41 49 public class GET extends HEAD { 50 51 static Log log = LogFactory.getLog(GET.class); 52 53 58 public static final String COLLECTION_MIME_TYPE = "text/html"; 59 60 65 public GET() { 66 super(); 67 } 68 69 74 public void process(DAVTransaction transaction, VFSResource resource) throws LockedException, IOException { 75 76 77 String handle = VFSLockManager.getNewHandle(); 78 VFSLockManager.getInstance().lock(resource, transaction.getSessionInfo(), false, true, handle); 79 80 try { 81 doHead(transaction, resource); 82 83 try { 84 if (resource.isCollection() || resource.isMount()) { 85 String mime = COLLECTION_MIME_TYPE + "; charset=\"utf-8\""; 86 transaction.setContentType(mime); 87 88 Util.noCache(transaction.getResponse()); 89 90 PrintWriter out = transaction.write("utf-8"); 91 String path = resource.getFullPath(); 92 out.println("<html>"); 93 out.println("<head>"); 94 out.println("<title>Collection: " + path + "</title>"); 95 out.println("</head>"); 96 out.println("<body>"); 97 out.println("<h2>Collection: " + path + "</h2>"); 98 out.println("<table>"); 99 out.println("<thead>"); 100 out.println("<tr>"); 101 out.println("<td>Name</td>"); 102 out.println("<td>Type</td>"); 103 out.println("<td>Size</td>"); 104 out.println("<td>Date</td>"); 105 out.println("</tr>"); 106 out.println("</thead>"); 107 out.println("<tbody>"); 108 109 110 VFSResource parent = resource.getParent(); 111 if (parent != null) { 112 out.println("<tr>"); 113 out.print("<td><li><a HREF=\"..\">../</a></td>"); 114 out.println("<td>Dir</td><td>"); 115 try { 116 out.println(parent.getFile().getContent().getSize()); 117 } 118 catch(Exception e) { 119 } 120 out.println("</td><td>"); 121 try { 122 out.println(SimpleDateFormat.getDateTimeInstance().format(new Date (parent.getFile().getContent().getLastModifiedTime()))); 123 } 124 catch(Exception e) { 125 } 126 out.println("</td></tr>"); 127 } 128 129 130 Iterator iterator = resource.getChildren(); 131 if (iterator != null) { 132 while (iterator.hasNext()) { 133 VFSResource child = (VFSResource) iterator.next(); 134 String childPath = child.getDisplayName(); 135 136 out.println("<tr>"); 137 out.print("<td><li><a HREF=\"" + child.getWebFolderPath() + "\">" + childPath + "</a></td>"); 138 if(child.isCollection()) 139 out.println("<td>Dir</td><td>"); 140 else if(child.isResource()) 141 out.println("<td>Resource</td><td>"); 142 else 143 out.println("<td>Unknown</td><td>"); 144 try { 145 out.println(child.getFile().getContent().getSize()); 146 } 147 catch(Exception e) { 148 } 149 out.println("</td><td>"); 150 try { 151 out.println(SimpleDateFormat.getDateTimeInstance().format(new Date (child.getFile().getContent().getLastModifiedTime()))); 152 } 153 catch(Exception e) { 154 } 155 out.println("</td></tr>"); 156 out.println("</tr>"); 157 } 158 } 159 out.println("</tbody>"); 160 out.println("</table>"); 161 out.println("</html>"); 162 out.flush(); 163 if(resource.getMount() != null) { 164 resource.getMount().resourceAccessList(resource, transaction, null); 165 } 166 return; 167 } 168 } catch (Exception e) { 169 if(resource.getMount() != null) { 170 resource.getMount().resourceAccessList(resource, transaction, e); 171 } 172 IOException ioe = new IOException (e.getMessage()); 173 ioe.initCause(e); 174 throw ioe; 175 } 176 177 int total = 0; 178 try { 179 180 Range[] ranges = null; 181 182 try { 183 ranges = processRangeHeader(transaction, resource); 184 } catch(IOException ex) { 185 ranges = null; 187 } 188 189 transaction.setHeader("Content-Type", resource.getContentType()); 190 191 resource.getMount().resourceAccessDownloading(resource, transaction); 192 193 OutputStream out = transaction.getOutputStream(); 194 byte buffer[] = new byte[32768]; 195 196 InputStream in = null; 197 198 try { 199 200 if(ranges == null || ranges.length > 1 ) { 201 202 in = resource.getInputStream(); 203 int k; 204 while ((k = in.read(buffer)) != -1) { 205 out.write(buffer, 0, k); 206 total += k; 207 } 208 } else { 209 210 211 RandomAccessContent content = resource.getFile().getContent().getRandomAccessContent(RandomAccessMode.READ); 212 213 content.seek(ranges[0].startPosition); 214 in = content.getInputStream(); 215 216 long count = ranges[0].count; 217 int k; 218 while(count > 0) { 219 while ((k = in.read(buffer, 0, (int) (count < buffer.length ? count : buffer.length))) != -1) { 220 out.write(buffer, 0, k); 221 total += k; 222 count -= k; 223 } 224 } 225 226 transaction.setHeader("Content-Range", "bytes " + ranges[0].startPosition 227 + "-" + ranges[0].startPosition 228 + ranges[0].count + "/" + resource.getFile().getContent().getSize()); 229 230 transaction.setStatus(206 ); 231 232 } 233 } 234 finally { 235 Util.closeStream(in); 236 } 237 resource.getMount().resourceAccessDownloadComplete(resource, transaction, null); 238 } catch (IOException ioe) { 239 resource.getMount().resourceAccessDownloadComplete(resource, transaction, ioe); 240 throw ioe; 241 } 242 } finally { 243 VFSLockManager.getInstance().unlock(transaction.getSessionInfo(), handle); 244 } 245 246 } 247 248 private Range[] processRangeHeader(DAVTransaction transaction, VFSResource resource) throws IOException { 249 250 try { 251 if(transaction.getRequest().getHeader("Range")!=null) { 252 253 String header = transaction.getRequest().getHeader("Range").toLowerCase(); 254 255 if(header.startsWith("bytes=")) { 256 257 Vector v = new Vector (); 258 259 StringTokenizer tokens = new StringTokenizer (header.substring(6), ","); 260 while(tokens.hasMoreTokens()) { 261 String r = tokens.nextToken(); 262 263 if(log.isDebugEnabled()) 264 log.debug("Processing byte range " + r); 265 266 int idx = r.indexOf('-'); 267 268 String startPoint = r.substring(0, idx); 269 String endPoint = r.substring(idx+1); 270 271 Range newRange = new Range(); 272 273 if("".equals(startPoint) && !"".equals(endPoint)) { 274 275 newRange.count = Long.parseLong(endPoint); 276 newRange.startPosition = resource.getFile().getContent().getSize() - newRange.count; 277 278 } else if(!"".equals(startPoint) && "".equals(endPoint)) { 279 280 newRange.startPosition = Long.parseLong(startPoint); 281 newRange.count = resource.getFile().getContent().getSize() - newRange.startPosition; 282 283 } else if(!"".equals(startPoint) && !"".equals(endPoint)) { 284 285 newRange.startPosition = Long.parseLong(startPoint); 286 newRange.count = Long.parseLong(endPoint) - newRange.startPosition; 287 288 } else { 289 log.error("Unsupported byte range element: " + r); 290 } 291 } 292 293 if(v.size() > 0) { 294 return (Range[]) v.toArray(new Range[0]); 295 } 296 } 297 298 } 299 } catch (Throwable t) { 300 log.error("Failed to process byte range header " + transaction.getRequest().getHeader("Range"), t); 301 throw new IOException ("Invalid range"); 302 } 303 304 return null; 305 } 306 307 308 class Range { 309 310 long startPosition; 311 long count; 312 } 313 } 314 | Popular Tags |