Search in sources :

Example 11 with Path

use of io.milton.common.Path in project lobcder by skoulouzis.

the class MiltonFsView method changeWorkingDirectory.

@Override
public boolean changeWorkingDirectory(String dir) throws FtpException {
    try {
        log.debug("cd: " + dir + " from " + currentPath);
        Path p = Path.path(dir);
        ResourceAndPath rp = getResource(p);
        if (rp.resource == null) {
            log.debug("not found: " + p);
            return false;
        } else if (rp.resource instanceof CollectionResource) {
            current = (CollectionResource) rp.resource;
            currentPath = rp.path;
            log.debug("currentPath is now: " + currentPath);
            return true;
        } else {
            log.debug("not a collection: " + rp.resource.getName());
            return false;
        }
    } catch (NotAuthorizedException ex) {
        throw new FtpException(ex);
    } catch (BadRequestException ex) {
        throw new FtpException(ex);
    }
}
Also used : Path(io.milton.common.Path) CollectionResource(io.milton.resource.CollectionResource) BadRequestException(io.milton.http.exceptions.BadRequestException) FtpException(org.apache.ftpserver.ftplet.FtpException) NotAuthorizedException(io.milton.http.exceptions.NotAuthorizedException)

Example 12 with Path

use of io.milton.common.Path in project lobcder by skoulouzis.

the class MiltonFsView method getFile.

@Override
public FtpFile getFile(String path) throws FtpException {
    try {
        log.debug("getFile: " + path);
        if (path.startsWith(".")) {
            path = currentPath.toString() + path.substring(1);
            log.debug("getFile2: " + path);
        }
        Path p = Path.path(path);
        ResourceAndPath rp = getResource(p);
        if (rp.resource == null) {
            log.debug("returning new file");
            return new MiltonFtpFile(this, rp.path, this.current, null, user);
        } else {
            return new MiltonFtpFile(this, rp.path, rp.resource, user);
        }
    } catch (NotAuthorizedException ex) {
        throw new FtpException(ex);
    } catch (BadRequestException ex) {
        throw new FtpException(ex);
    }
}
Also used : Path(io.milton.common.Path) BadRequestException(io.milton.http.exceptions.BadRequestException) FtpException(org.apache.ftpserver.ftplet.FtpException) NotAuthorizedException(io.milton.http.exceptions.NotAuthorizedException)

Example 13 with Path

use of io.milton.common.Path in project lobcder by skoulouzis.

the class MkColHandler method process.

public void process(HttpManager manager, Request request, Response response, CollectionResourceCreator creator) throws ConflictException, NotAuthorizedException, BadRequestException, IOException {
    if (!handlerHelper.checkExpects(responseHandler, request, response)) {
        return;
    }
    String host = request.getHostHeader();
    String finalurl = HttpManager.decodeUrl(request.getAbsolutePath());
    String name;
    if (log.isDebugEnabled()) {
        log.debug("process request: host: " + host + " url: " + finalurl);
    }
    // this is the parent collection it goes in
    Path finalpath = Path.path(finalurl);
    name = finalpath.getName();
    Path parent = finalpath.getParent();
    String parenturl = parent.toString();
    Resource parentcol = manager.getResourceFactory().getResource(host, parenturl);
    if (parentcol != null) {
        log.debug("process: resource: " + parentcol.getClass().getName());
        if (handlerHelper.isNotCompatible(parentcol, request.getMethod())) {
            log.debug("resource not compatible. Resource class: " + parentcol.getClass() + " handler: " + getClass());
            responseHandler.respondMethodNotImplemented(parentcol, response, request);
            return;
        }
        if (handlerHelper.isLockedOut(request, parentcol)) {
            log.warn("isLockedOut");
            response.setStatus(Status.SC_LOCKED);
            return;
        }
        Resource dest = manager.getResourceFactory().getResource(host, finalpath.toString());
        if (dest != null && handlerHelper.isLockedOut(request, dest)) {
            log.info("destination exists and is locked");
            responseHandler.respondLocked(request, response, dest);
            return;
        } else if (handlerHelper.missingLock(request, parentcol)) {
            log.info("precondition failed");
            // notowner_modify wants this code here
            response.setStatus(Status.SC_PRECONDITION_FAILED);
            return;
        }
        if (parentcol instanceof CollectionResource) {
            CollectionResource col = (CollectionResource) parentcol;
            if (log.isTraceEnabled()) {
                log.trace("process mkcol on parent: " + parentcol.getClass() + " with creator: " + creator.getClass());
            }
            processMakeCol(manager, request, response, col, name, creator);
        } else {
            log.warn("parent collection is no a CollectionResource: " + parentcol.getName());
            responseHandler.respondConflict(parentcol, response, request, "not a collection");
        }
    } else {
        log.warn("parent does not exist: host=" + host + " path=" + parenturl);
        manager.getResponseHandler().respondConflict(parentcol, response, request, name);
    }
}
Also used : Path(io.milton.common.Path) CollectionResource(io.milton.resource.CollectionResource) MakeCollectionableResource(io.milton.resource.MakeCollectionableResource) CollectionResource(io.milton.resource.CollectionResource) Resource(io.milton.resource.Resource)

Example 14 with Path

use of io.milton.common.Path in project lobcder by skoulouzis.

the class JsonResourceFactory method getResource.

@Override
public Resource getResource(String host, String sPath) throws NotAuthorizedException, BadRequestException {
    LogUtils.trace(log, "getResource", host, sPath);
    Path path = Path.path(sPath);
    Path parent = path.getParent();
    Request request = HttpManager.request();
    String encodedPath = request.getAbsolutePath();
    if (isMatchingPath(parent)) {
        log.trace("getResource: is matching path");
        Path resourcePath = parent.getParent();
        if (resourcePath != null) {
            String method = path.getName();
            Resource wrappedResource = wrapped.getResource(host, resourcePath.toString());
            if (wrappedResource != null) {
                Resource r = wrapResource(host, wrappedResource, method, encodedPath);
                LogUtils.trace(log, "returning a", r.getClass());
                return r;
            }
        }
    } else if (isAjaxLoginPath(sPath)) {
        Resource h = wrapped.getResource(host, "/");
        if (h == null) {
            log.info("Found a login path, but couldnt get a root resource to delegate login to");
            return null;
        } else {
            return new AjaxLoginResource(sPath, h);
        }
    } else {
        log.trace("getResource: not matching path");
        return wrapped.getResource(host, sPath);
    }
    return null;
}
Also used : Path(io.milton.common.Path) Request(io.milton.http.Request)

Example 15 with Path

use of io.milton.common.Path in project lobcder by skoulouzis.

the class WorkerServlet method processRequest.

/**
 * Process the actual request.
 *
 * @param request The request to be processed.
 * @param response The response to be created.
 * @param content Whether the request body should be written (GET) or not
 * (HEAD).
 * @throws IOException If something fails at I/O level.
 */
private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException, InterruptedException, URISyntaxException, VlException, JAXBException {
    long startTime = System.currentTimeMillis();
    // Get requested file by path info.
    String requestedFile = request.getPathInfo();
    // Check if file is actually supplied to the request URL.
    PDRI pdri = null;
    if (requestedFile == null || requestedFile.split("/").length < 2) {
        // Do your thing if the file is not supplied to the request URL.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    Path pathAndToken = Path.path(requestedFile);
    // token = pathAndToken.getName();
    fileUID = pathAndToken.getParent().toString().replaceAll("/", "");
    // Logger.getLogger(WorkerServlet.class.getName()).log(Level.FINE, "token: {0} fileUID: {1}", new Object[]{token, fileUID});
    pdri = cat.getPDRI(fileUID);
    fileLogicalName = cat.getLogicalDataWrapped(fileUID).getLogicalData().getName();
    // Check if file actually exists in filesystem.
    if (pdri == null) {
        // Do your thing if the file appears to be non-existing.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    // Prepare some variables. The ETag is an unique identifier of the file.
    long length = pdri.getLength();
    LogicalDataWrapped ldw = Catalogue.logicalDataCache.get(fileUID);
    long lastModified;
    if (ldw != null) {
        LogicalData ld = ldw.getLogicalData();
        lastModified = ld.getModifiedDate();
    } else {
        lastModified = System.currentTimeMillis();
    }
    String eTag = fileLogicalName + "_" + length + "_" + lastModified;
    long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME;
    // Validate request headers for caching ---------------------------------------------------
    // If-None-Match header should contain "*" or ETag. If so, then return 304.
    String ifNoneMatch = request.getHeader("If-None-Match");
    if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        // Required in 304.
        response.setHeader("ETag", eTag);
        // Postpone cache with 1 week.
        response.setDateHeader("Expires", expires);
        return;
    }
    // If-Modified-Since header should be greater than LastModified. If so, then return 304.
    // This header is ignored if any If-None-Match header is specified.
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        // Required in 304.
        response.setHeader("ETag", eTag);
        // Postpone cache with 1 week.
        response.setDateHeader("Expires", expires);
        return;
    }
    // Validate request headers for resume ----------------------------------------------------
    // If-Match header should contain "*" or ETag. If not, then return 412.
    String ifMatch = request.getHeader("If-Match");
    if (ifMatch != null && !matches(ifMatch, eTag)) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }
    // If-Unmodified-Since header should be greater than LastModified. If not, then return 412.
    long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
    if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }
    // Validate and process range -------------------------------------------------------------
    // Prepare some variables. The full Range represents the complete file.
    Range full = new Range(0, length - 1, length);
    List<Range> ranges = new ArrayList<>();
    // Validate and process Range and If-Range headers.
    String range = request.getHeader("Range");
    if (range != null) {
        // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416.
        if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
            // Required in 416.
            response.setHeader("Content-Range", "bytes */" + length);
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }
        // If-Range header should either match ETag or be greater then LastModified. If not,
        // then return full file.
        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(eTag)) {
            try {
                // Throws IAE if invalid.
                long ifRangeTime = request.getDateHeader("If-Range");
                if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
                    ranges.add(full);
                }
            } catch (IllegalArgumentException ignore) {
                ranges.add(full);
            }
        }
        // If any valid If-Range header, then process each part of byte range.
        if (ranges.isEmpty()) {
            for (String part : range.substring(6).split(",")) {
                // Assuming a file with length of 100, the following examples returns bytes at:
                // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100).
                long start = sublong(part, 0, part.indexOf("-"));
                long end = sublong(part, part.indexOf("-") + 1, part.length());
                if (start == -1) {
                    start = length - end;
                    end = length - 1;
                } else if (end == -1 || end > length - 1) {
                    end = length - 1;
                }
                // Check if Range is syntactically valid. If not, then return 416.
                if (start > end) {
                    // Required in 416.
                    response.setHeader("Content-Range", "bytes */" + length);
                    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                    return;
                }
                // Add range.
                ranges.add(new Range(start, end, length));
            }
        }
    }
    // Prepare and initialize response --------------------------------------------------------
    // Get content type by file name and set default GZIP support and content disposition.
    String contentType = getServletContext().getMimeType(fileLogicalName);
    ldw = Catalogue.logicalDataCache.get(fileUID);
    if (contentType == null && ldw != null) {
        contentType = ldw.getLogicalData().getContentTypesAsString();
    } else {
        contentType = "application/octet-stream";
    }
    boolean acceptsGzip = false;
    String disposition = "inline";
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "application/octet-stream";
    }
    // the browser and expand content type with the one and right character encoding.
    if (contentType.startsWith("text")) {
        String acceptEncoding = request.getHeader("Accept-Encoding");
        acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    } else // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
    if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment";
    }
    // Initialize response.
    response.reset();
    if (setResponseBufferSize) {
        response.setBufferSize(bufferSize);
    }
    response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileLogicalName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", expires);
    ldw = Catalogue.logicalDataCache.get(fileUID);
    if (ldw != null) {
        response.setContentLength(safeLongToInt(ldw.getLogicalData().getLength()));
    }
    // Send requested file (part(s)) to client ------------------------------------------------
    // Prepare streams.
    // RandomAccessFile input = null;
    OutputStream output = null;
    try {
        // Open streams.
        // input = new RandomAccessFile(file, "r");
        // input = pdri.getData()
        output = response.getOutputStream();
        if (ranges.isEmpty() || ranges.get(0) == full) {
            // Return full file.
            Range r = full;
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            if (content) {
                if (acceptsGzip) {
                    // The browser accepts GZIP, so GZIP the content.
                    response.setHeader("Content-Encoding", "gzip");
                    output = new GZIPOutputStream(output, bufferSize);
                } else {
                    // Content length is not directly predictable in case of GZIP.
                    // So only add it if there is no means of GZIP, else browser will hang.
                    response.setHeader("Content-Length", String.valueOf(r.length));
                }
                // Copy full range.
                copy(pdri, output, r.start, r.length, request);
            }
        } else if (ranges.size() == 1) {
            // Return single part of file.
            Range r = ranges.get(0);
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            response.setHeader("Content-Length", String.valueOf(r.length));
            // 206.
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            if (content) {
                // Copy single part range.
                copy(pdri, output, r.start, r.length, request);
            }
        } else {
            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
            // 206.
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            if (content) {
                // Cast back to ServletOutputStream to get the easy println methods.
                ServletOutputStream sos = (ServletOutputStream) output;
                // Copy multi part range.
                for (Range r : ranges) {
                    // Add multipart boundary and header fields for every range.
                    sos.println();
                    sos.println("--" + MULTIPART_BOUNDARY);
                    sos.println("Content-Type: " + contentType);
                    sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);
                    // Copy single part range of multi part range.
                    copy(pdri, output, r.start, r.length, request);
                }
                // End with multipart boundary.
                sos.println();
                sos.println("--" + MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        close(output);
        if (in != null) {
            in.close();
        }
        long elapsed = System.currentTimeMillis() - startTime;
        if (elapsed <= 0) {
            elapsed = 1;
        }
        LogicalDataWrapped lwd = Catalogue.logicalDataCache.get(fileUID);
        if (lwd != null) {
            double speed = ((lwd.getLogicalData().getLength() * 8.0) * 1000.0) / (elapsed * 1000.0);
            Double oldSpeed = Catalogue.weightPDRIMap.get(pdri.getHost());
            if (oldSpeed == null) {
                oldSpeed = speed;
            }
            Integer numOfGets = numOfGetsMap.get(pdri.getHost());
            if (numOfGets == null) {
                numOfGets = 1;
            }
            double averagre = (speed + oldSpeed) / (double) numOfGets;
            numOfGetsMap.put(pdri.getHost(), numOfGets++);
            Catalogue.weightPDRIMap.put(pdri.getHost(), averagre);
            Stats stats = new Stats();
            stats.setSource(request.getLocalAddr());
            stats.setDestination(request.getRemoteAddr());
            stats.setSpeed(speed);
            stats.setSize(Catalogue.logicalDataCache.get(fileUID).getLogicalData().getLength());
            cat.setSpeed(stats);
            String speedMsg = "Source: " + request.getLocalAddr() + " Destination: " + request.getRemoteAddr() + " Tx_Speed: " + speed + " Kbites/sec Tx_Size: " + Catalogue.logicalDataCache.get(fileUID).getLogicalData().getLength() + " bytes";
            Logger.getLogger(WorkerServlet.class.getName()).log(Level.INFO, speedMsg);
            String averageSpeedMsg = "Average speed: Source: " + pdri.getHost() + " Destination: " + request.getLocalAddr() + " Rx_Speed: " + averagre + " Kbites/sec Rx_Size: " + Catalogue.logicalDataCache.get(fileUID).getLogicalData().getLength() + " bytes";
            if (Util.sendStats()) {
                stats.setSource(request.getLocalAddr());
                stats.setDestination(request.getRemoteAddr());
                stats.setSpeed(speed);
                stats.setSize(Catalogue.logicalDataCache.get(fileUID).getLogicalData().getLength());
                cat.setSpeed(stats);
            }
            Logger.getLogger(WorkerServlet.class.getName()).log(Level.INFO, averageSpeedMsg);
        }
    }
}
Also used : Path(io.milton.common.Path) ServletOutputStream(javax.servlet.ServletOutputStream) GZIPOutputStream(java.util.zip.GZIPOutputStream) ServletOutputStream(javax.servlet.ServletOutputStream) TeeOutputStream(org.apache.commons.io.output.TeeOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) LogicalDataWrapped(nl.uva.cs.lobcder.rest.wrappers.LogicalDataWrapped) PDRI(nl.uva.cs.lobcder.resources.PDRI) LogicalData(nl.uva.cs.lobcder.resources.LogicalData) GZIPOutputStream(java.util.zip.GZIPOutputStream) Stats(nl.uva.cs.lobcder.rest.wrappers.Stats)

Aggregations

Path (io.milton.common.Path)25 Resource (io.milton.resource.Resource)9 CollectionResource (io.milton.resource.CollectionResource)8 LogicalData (nl.uva.cs.lobcder.resources.LogicalData)7 BadRequestException (io.milton.http.exceptions.BadRequestException)6 SQLException (java.sql.SQLException)5 NotAuthorizedException (io.milton.http.exceptions.NotAuthorizedException)4 Connection (java.sql.Connection)4 ConflictException (io.milton.http.exceptions.ConflictException)3 MakeCollectionableResource (io.milton.resource.MakeCollectionableResource)3 File (java.io.File)3 Permissions (nl.uva.cs.lobcder.auth.Permissions)3 GetableResource (io.milton.resource.GetableResource)2 PostableResource (io.milton.resource.PostableResource)2 PutableResource (io.milton.resource.PutableResource)2 ReplaceableResource (io.milton.resource.ReplaceableResource)2 MalformedURLException (java.net.MalformedURLException)2 URL (java.net.URL)2 ArrayList (java.util.ArrayList)2 PDRI (nl.uva.cs.lobcder.resources.PDRI)2