Example usage for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT

List of usage examples for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT.

Prototype

int SC_PARTIAL_CONTENT

To view the source code for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT.

Click Source Link

Document

Status code (206) indicating that the server has fulfilled the partial GET request for the resource.

Usage

From source file:com.liferay.lms.servlet.SCORMFileServerServlet.java

/**
 * Procesa los metodos HTTP GET y POST.<br>
 * Busca en la ruta que se le ha pedido el comienzo del directorio
 * "contenidos" y sirve el fichero.//from   ww  w . jav a  2  s  . c  o m
 */
protected void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content)
        throws ServletException, java.io.IOException {
    String mime_type;
    String charset;
    String patharchivo;
    String uri;

    try {
        User user = PortalUtil.getUser(request);

        if (user == null) {
            String userId = null;
            String companyId = null;
            Cookie[] cookies = ((HttpServletRequest) request).getCookies();
            if (Validator.isNotNull(cookies)) {
                for (Cookie c : cookies) {
                    if ("COMPANY_ID".equals(c.getName())) {
                        companyId = c.getValue();
                    } else if ("ID".equals(c.getName())) {
                        userId = hexStringToStringByAscii(c.getValue());
                    }
                }
            }

            if (userId != null && companyId != null) {
                try {
                    Company company = CompanyLocalServiceUtil.getCompany(Long.parseLong(companyId));
                    Key key = company.getKeyObj();

                    String userIdPlain = Encryptor.decrypt(key, userId);

                    user = UserLocalServiceUtil.getUser(Long.valueOf(userIdPlain));

                    // Now you can set the liferayUser into a thread local
                    // for later use or
                    // something like that.

                } catch (Exception pException) {
                    throw new RuntimeException(pException);
                }
            }
        }

        String rutaDatos = SCORMContentLocalServiceUtil.getBaseDir();

        // Se comprueba que el usuario tiene permisos para acceder.
        // Damos acceso a todo el mundo al directorio "personalizacion",
        // para permitir mostrar a todos la pantalla de identificacion.
        uri = URLDecoder.decode(request.getRequestURI(), "UTF-8");
        uri = uri.substring(uri.indexOf("scorm/") + "scorm/".length());
        patharchivo = rutaDatos + "/" + uri;

        String[] params = uri.split("/");
        long groupId = GetterUtil.getLong(params[1]);
        String uuid = params[2];
        SCORMContent scormContent = SCORMContentLocalServiceUtil.getSCORMContentByUuidAndGroupId(uuid, groupId);

        boolean allowed = false;
        if (user == null) {
            user = UserLocalServiceUtil.getDefaultUser(PortalUtil.getDefaultCompanyId());
        }
        PermissionChecker pc = PermissionCheckerFactoryUtil.create(user);
        allowed = pc.hasPermission(groupId, SCORMContent.class.getName(), scormContent.getScormId(),
                ActionKeys.VIEW);
        if (!allowed) {
            AssetEntry scormAsset = AssetEntryLocalServiceUtil.getEntry(SCORMContent.class.getName(),
                    scormContent.getPrimaryKey());
            long scormAssetId = scormAsset.getEntryId();
            int typeId = new Long((new SCORMLearningActivityType()).getTypeId()).intValue();
            long[] groupIds = user.getGroupIds();
            for (long gId : groupIds) {
                List<LearningActivity> acts = LearningActivityLocalServiceUtil
                        .getLearningActivitiesOfGroupAndType(gId, typeId);
                for (LearningActivity act : acts) {
                    String entryId = LearningActivityLocalServiceUtil.getExtraContentValue(act.getActId(),
                            "assetEntry");
                    if (Validator.isNotNull(entryId) && Long.valueOf(entryId) == scormAssetId) {
                        allowed = pc.hasPermission(gId, LearningActivity.class.getName(), act.getActId(),
                                ActionKeys.VIEW);
                        if (allowed) {
                            break;
                        }
                    }
                }
                if (allowed) {
                    break;
                }
            }

        }
        if (allowed) {

            File archivo = new File(patharchivo);

            // Si el archivo existe y no es un directorio se sirve. Si no,
            // no se hace nada.
            if (archivo.exists() && archivo.isFile()) {

                // El content type siempre antes del printwriter
                mime_type = MimeTypesUtil.getContentType(archivo);
                charset = "";
                if (archivo.getName().toLowerCase().endsWith(".html")
                        || archivo.getName().toLowerCase().endsWith(".htm")) {
                    mime_type = "text/html";
                    if (isISO(FileUtils.readFileToString(archivo))) {
                        charset = "ISO-8859-1";
                    }
                }
                if (archivo.getName().toLowerCase().endsWith(".swf")) {
                    mime_type = "application/x-shockwave-flash";
                }
                if (archivo.getName().toLowerCase().endsWith(".mp4")) {
                    mime_type = "video/mp4";
                }
                if (archivo.getName().toLowerCase().endsWith(".flv")) {
                    mime_type = "video/x-flv";
                }
                response.setContentType(mime_type);
                if (Validator.isNotNull(charset)) {
                    response.setCharacterEncoding(charset);

                }
                response.addHeader("Content-Type",
                        mime_type + (Validator.isNotNull(charset) ? "; " + charset : ""));
                /*if (archivo.getName().toLowerCase().endsWith(".swf")
                      || archivo.getName().toLowerCase().endsWith(".flv")) {
                   response.addHeader("Content-Length",
                String.valueOf(archivo.length()));
                }
                */
                if (archivo.getName().toLowerCase().endsWith("imsmanifest.xml")) {
                    FileInputStream fis = new FileInputStream(patharchivo);

                    String sco = ParamUtil.get(request, "scoshow", "");
                    Document manifest = SAXReaderUtil.read(fis);
                    if (sco.length() > 0) {

                        Element organizatEl = manifest.getRootElement().element("organizations")
                                .element("organization");
                        Element selectedItem = selectItem(organizatEl, sco);
                        if (selectedItem != null) {
                            selectedItem.detach();
                            java.util.List<Element> items = organizatEl.elements("item");
                            for (Element item : items) {

                                organizatEl.remove(item);
                            }
                            organizatEl.add(selectedItem);
                        }
                    }
                    //clean unused resources.
                    Element resources = manifest.getRootElement().element("resources");
                    java.util.List<Element> theResources = resources.elements("resource");
                    Element organizatEl = manifest.getRootElement().element("organizations")
                            .element("organization");
                    java.util.List<String> identifiers = getIdentifierRefs(organizatEl);
                    for (Element resource : theResources) {
                        String identifier = resource.attributeValue("identifier");
                        if (!identifiers.contains(identifier)) {
                            resources.remove(resource);
                        }
                    }
                    response.getWriter().print(manifest.asXML());
                    fis.close();
                    return;

                }

                if (mime_type.startsWith("text") || mime_type.endsWith("javascript")
                        || mime_type.equals("application/xml")) {

                    java.io.OutputStream out = response.getOutputStream();
                    FileInputStream fis = new FileInputStream(patharchivo);

                    byte[] buffer = new byte[512];
                    int i = 0;

                    while (fis.available() > 0) {
                        i = fis.read(buffer);
                        if (i == 512)
                            out.write(buffer);
                        else
                            out.write(buffer, 0, i);

                    }

                    fis.close();
                    out.flush();
                    out.close();
                    return;
                }
                //If not manifest
                String fileName = archivo.getName();
                long length = archivo.length();
                long lastModified = archivo.lastModified();
                String eTag = fileName + "_" + length + "_" + lastModified;
                long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME;
                String ifNoneMatch = request.getHeader("If-None-Match");
                if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    response.setHeader("ETag", eTag); // Required in 304.
                    response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
                    return;
                }
                long ifModifiedSince = request.getDateHeader("If-Modified-Since");
                if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    response.setHeader("ETag", eTag); // Required in 304.
                    response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
                    return;
                }

                // 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<Range>();

                // 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*)*$")) {
                        response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                        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 {
                            long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                            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) {
                                response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                                response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                                return;
                            }

                            // Add range.
                            ranges.add(new Range(start, end, length));
                        }
                    }
                }
                boolean acceptsGzip = false;
                String disposition = "inline";

                if (mime_type.startsWith("text")) {
                    //String acceptEncoding = request.getHeader("Accept-Encoding");
                    // acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip");
                    // mime_type += ";charset=UTF-8";
                }

                // Else, expect for images, determine content disposition. If content type is supported by
                // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
                else if (!mime_type.startsWith("image")) {
                    String accept = request.getHeader("Accept");
                    disposition = accept != null && accepts(accept, mime_type) ? "inline" : "attachment";
                }

                // Initialize response.
                response.reset();
                response.setBufferSize(DEFAULT_BUFFER_SIZE);
                response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
                response.setHeader("Accept-Ranges", "bytes");
                response.setHeader("ETag", eTag);
                response.setDateHeader("Last-Modified", lastModified);
                response.setDateHeader("Expires", expires);

                // Send requested file (part(s)) to client ------------------------------------------------

                // Prepare streams.
                RandomAccessFile input = null;
                OutputStream output = null;

                try {
                    // Open streams.
                    input = new RandomAccessFile(archivo, "r");
                    output = response.getOutputStream();

                    if (ranges.isEmpty() || ranges.get(0) == full) {

                        // Return full file.
                        Range r = full;
                        response.setContentType(mime_type);
                        response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);

                        if (content) {

                            // 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(input, output, r.start, r.length);
                        }

                    } else if (ranges.size() == 1) {

                        // Return single part of file.
                        Range r = ranges.get(0);
                        response.setContentType(mime_type);
                        response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
                        response.setHeader("Content-Length", String.valueOf(r.length));
                        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

                        if (content) {
                            // Copy single part range.
                            copy(input, output, r.start, r.length);
                        }

                    } else {

                        // Return multiple parts of file.
                        response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
                        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

                        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: " + mime_type);
                                sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);

                                // Copy single part range of multi part range.
                                copy(input, output, r.start, r.length);
                            }

                            // End with multipart boundary.
                            sos.println();
                            sos.println("--" + MULTIPART_BOUNDARY + "--");
                        }
                    }
                } finally {
                    // Gently close streams.
                    close(output);
                    close(input);
                }
            } else {
                //java.io.OutputStream out = response.getOutputStream();
                response.sendError(404);
                //out.write(uri.getBytes());
            }
        } else {
            response.sendError(401);
        }
    } catch (Exception e) {
        System.out.println("Error en el processRequest() de ServidorArchivos: " + e.getMessage());
    }
}

From source file:de.digitalcollections.streaming.euphoria.controller.StreamingController.java

private String setContentHeaders(HttpServletRequest request, HttpServletResponse response,
        ResourceInfo resourceInfo, List<Range> ranges) {
    String contentType = resourceInfo.contentType;
    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "application/octet-stream";
    }/*from  w  w w .  ja  v a  2 s  . c  o  m*/
    String disposition = isAttachment(request, contentType) ? "attachment" : "inline";
    String filename = encodeURI(resourceInfo.fileName);
    response.setHeader("Content-Disposition", String.format(CONTENT_DISPOSITION_HEADER, disposition, filename));
    response.setHeader("Accept-Ranges", "bytes");

    if (ranges.size() == 1) {
        Range range = ranges.get(0);
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(range.length));

        if (response.getStatus() == HttpServletResponse.SC_PARTIAL_CONTENT) {
            response.setHeader("Content-Range",
                    "bytes " + range.start + "-" + range.end + "/" + resourceInfo.length);
        }
    } else {
        response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
    }

    return contentType;
}

From source file:org.sakaiproject.sdata.tool.JCRHandler.java

@Override
public void doGet(final HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    OutputStream out = null;// www .  j a  v a2s .co m
    InputStream in = null;
    try {
        snoopRequest(request);

        ResourceDefinition rp = resourceDefinitionFactory.getSpec(request);
        SDataFunction m = resourceFunctionFactory.get(rp.getFunctionDefinition());

        if (describe(request, response, m)) {
            return;
        }

        Node n = jcrNodeFactory.getNode(rp.getRepositoryPath());
        if (n == null) {
            response.reset();
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        String primaryNodeType = n.getPrimaryNodeType().getName();
        String version = rp.getVersion();
        if (version != null) {
            try {
                n = n.getVersionHistory().getVersion(version);
            } catch (VersionException e) {
                throw new SDataAccessException(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
            }
            n = n.getNode(JCRConstants.JCR_FROZENNODE);
            if (n.hasProperty(JCRConstants.JCR_FROZENPRIMARYTYPE)) {
                primaryNodeType = n.getProperty(JCRConstants.JCR_FROZENPRIMARYTYPE).getString();
            }
        }

        if (m != null) {
            m.call(this, request, response, n, rp);
        } else {

            if (JCRConstants.NT_FILE.equals(primaryNodeType)) {

                Node resource = n.getNode(JCRConstants.JCR_CONTENT);
                Property lastModified = resource.getProperty(JCRConstants.JCR_LASTMODIFIED);
                Property mimeType = resource.getProperty(JCRConstants.JCR_MIMETYPE);
                Property content = resource.getProperty(JCRConstants.JCR_DATA);

                response.setContentType(mimeType.getString());
                if (mimeType.getString().startsWith("text")) {
                    if (resource.hasProperty(JCRConstants.JCR_ENCODING)) {
                        Property encoding = resource.getProperty(JCRConstants.JCR_ENCODING);
                        response.setCharacterEncoding(encoding.getString());
                    }
                }
                response.setDateHeader(LAST_MODIFIED, lastModified.getDate().getTimeInMillis());
                setGetCacheControl(response, rp.isPrivate());

                String currentEtag = String.valueOf(lastModified.getDate().getTimeInMillis());
                response.setHeader("ETag", currentEtag);

                long lastModifiedTime = lastModified.getDate().getTimeInMillis();

                if (!checkPreconditions(request, response, lastModifiedTime, currentEtag)) {
                    return;
                }
                long totallength = content.getLength();
                long[] ranges = new long[2];
                ranges[0] = 0;
                ranges[1] = totallength;
                if (!checkRanges(request, response, lastModifiedTime, currentEtag, ranges)) {
                    return;
                }

                long length = ranges[1] - ranges[0];

                if (totallength != length) {
                    response.setHeader("Accept-Ranges", "bytes");
                    response.setDateHeader("Last-Modified", lastModifiedTime);
                    response.setHeader("Content-Range",
                            "bytes " + ranges[0] + "-" + (ranges[1] - 1) + "/" + totallength);
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

                    LOG.info("Partial Content Sent " + HttpServletResponse.SC_PARTIAL_CONTENT);
                } else {
                    response.setStatus(HttpServletResponse.SC_OK);
                }

                response.setContentLength((int) length);

                out = response.getOutputStream();

                in = content.getStream();
                long loc = in.skip(ranges[0]);
                if (loc != ranges[0]) {
                    throw new RestServiceFaultException(HttpServletResponse.SC_BAD_REQUEST,
                            "Range specified is invalid asked for " + ranges[0] + " got " + loc);
                }
                byte[] b = new byte[10240];
                int nbytes = 0;
                while ((nbytes = in.read(b)) > 0 && length > 0) {
                    if (nbytes < length) {
                        out.write(b, 0, nbytes);
                        length = length - nbytes;
                    } else {
                        out.write(b, 0, (int) length);
                        length = 0;
                    }
                }
            } else {
                boolean handled = handleSmartNode(request, response, rp, n);
                if (!handled) {
                    doDefaultGet(request, response, rp, n);
                }
            }
        }
    } catch (UnauthorizedException ape) {
        // catch any Unauthorized exceptions and send a 401
        response.reset();
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ape.getMessage());
    } catch (PermissionDeniedException pde) {
        // catch any permission denied exceptions, and send a 403
        response.reset();
        response.sendError(HttpServletResponse.SC_FORBIDDEN, pde.getMessage());

    } catch (SDataException e) {
        LOG.error("Failed  To service Request " + e.getMessage());
        e.printStackTrace();
        sendError(request, response, e);
    } catch (Exception e) {
        LOG.error("Failed  TO service Request ", e);
        sendError(request, response, e);
        snoopRequest(request);
    } finally {

        try {
            out.close();
        } catch (Exception ex) {
        }
        try {
            in.close();
        } catch (Exception ex) {
        }
    }
}

From source file:edu.chalmers.dat076.moviefinder.controller.FileController.java

/**
 * Process the actual request./*from   w ww.  j ava  2 s . com*/
 *
 * @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,
        String path, String defaultContentType) throws IOException {
    // Validate the requested file ------------------------------------------------------------

    // URL-decode the file name (might contain spaces and on) and prepare file object.
    File file = new File(path);

    // Check if file actually exists in filesystem.
    if (!file.exists()) {
        // 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.
    String fileName = file.getName();
    long length = file.length();
    long lastModified = file.lastModified();
    String eTag = fileName + "_" + length + "_" + lastModified;
    long expires = System.currentTimeMillis() + FileControllerUtils.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 && FileControllerUtils.matches(ifNoneMatch, eTag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        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);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        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 && !FileControllerUtils.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*)*$")) {
            response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
            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 {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                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 = FileControllerUtils.sublong(part, 0, part.indexOf("-"));
                long end = FileControllerUtils.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) {
                    response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                    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 = request.getServletContext().getMimeType(fileName);
    boolean acceptsGzip = false;
    String disposition = "inline";

    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    //if (contentType == null) {
    contentType = defaultContentType;
    //}

    // If content type is text, then determine whether GZIP content encoding is supported by
    // 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 && FileControllerUtils.accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    } // Else, expect for images, determine content disposition. If content type is supported by
      // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
    else if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && FileControllerUtils.accepts(accept, contentType) ? "inline"
                : "attachment";
    }

    // Initialize response.
    response.reset();
    response.setBufferSize(FileControllerUtils.DEFAULT_BUFFER_SIZE);
    //response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", expires);

    // Send requested file (part(s)) to client ------------------------------------------------
    // Prepare streams.
    RandomAccessFile input = null;
    OutputStream output = null;

    try {
        // Open streams.
        input = new RandomAccessFile(file, "r");
        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, FileControllerUtils.DEFAULT_BUFFER_SIZE);
                } 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.
                FileControllerUtils.copy(input, output, r.start, r.length);
            }

        } 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));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Copy single part range.
                FileControllerUtils.copy(input, output, r.start, r.length);
            }

        } else {

            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + FileControllerUtils.MULTIPART_BOUNDARY);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            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("--" + FileControllerUtils.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.
                    FileControllerUtils.copy(input, output, r.start, r.length);
                }

                // End with multipart boundary.
                sos.println();
                sos.println("--" + FileControllerUtils.MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        FileControllerUtils.close(output);
        FileControllerUtils.close(input);
    }
}

From source file:net.yacy.http.servlets.YaCyDefaultServlet.java

/**
 * send static content//from   w  ww.j  a va  2  s.c  om
 * 
 * @param request
 * @param response
 * @param include  is a include file (send without changing/adding headers)
 * @param resource the static content
 * @param reqRanges
 * @throws IOException 
 */
protected void sendData(HttpServletRequest request, HttpServletResponse response, boolean include,
        Resource resource, Enumeration<String> reqRanges) throws IOException {

    final long content_length = resource.length();

    // Get the output stream (or writer)
    OutputStream out;
    try {
        out = response.getOutputStream();
    } catch (IllegalStateException e) {
        out = new WriterOutputStream(response.getWriter());
    }

    // remove the last-modified field since caching otherwise does not work
    /*
       https://www.ietf.org/rfc/rfc2616.txt
       "if the response does have a Last-Modified time, the heuristic
       expiration value SHOULD be no more than some fraction of the interval
       since that time. A typical setting of this fraction might be 10%."
    */
    if (response.containsHeader(HeaderFramework.LAST_MODIFIED)) {
        response.getHeaders(HeaderFramework.LAST_MODIFIED).clear(); // if this field is present, the reload-time is a 10% fraction of ttl and other caching headers do not work
    }

    // cache-control: allow shared caching (i.e. proxies) and set expires age for cache
    response.setHeader(HeaderFramework.CACHE_CONTROL, "public, max-age=" + Integer.toString(600)); // seconds; ten minutes

    if (reqRanges == null || !reqRanges.hasMoreElements() || content_length < 0) {
        //  if there were no ranges, send entire entity
        if (include) {
            resource.writeTo(out, 0, content_length);
        } else {
            writeHeaders(response, resource, content_length);
            resource.writeTo(out, 0, content_length);
        }
    } else {
        // Parse the satisfiable ranges
        List<?> ranges = InclusiveByteRange.satisfiableRanges(reqRanges, content_length);

        //  if there are no satisfiable ranges, send 416 response
        if (ranges == null || ranges.isEmpty()) {
            writeHeaders(response, resource, content_length);
            response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            response.setHeader(HttpHeader.CONTENT_RANGE.asString(),
                    InclusiveByteRange.to416HeaderRangeString(content_length));
            resource.writeTo(out, 0, content_length);
            out.close();
            return;
        }

        //  if there is only a single valid range (must be satisfiable
        //  since were here now), send that range with a 216 response
        if (ranges.size() == 1) {
            InclusiveByteRange singleSatisfiableRange = (InclusiveByteRange) ranges.get(0);
            long singleLength = singleSatisfiableRange.getSize(content_length);
            writeHeaders(response, resource, singleLength);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            response.setHeader(HttpHeader.CONTENT_RANGE.asString(),
                    singleSatisfiableRange.toHeaderRangeString(content_length));
            resource.writeTo(out, singleSatisfiableRange.getFirst(content_length), singleLength);
            out.close();
            return;
        }

        //  multiple non-overlapping valid ranges cause a multipart
        //  216 response which does not require an overall
        //  content-length header
        //
        writeHeaders(response, resource, -1);
        String mimetype = response.getContentType();
        if (mimetype == null) {
            ConcurrentLog.warn("FILEHANDLER",
                    "YaCyDefaultServlet: Unknown mimetype for " + request.getRequestURI());
        }
        MultiPartOutputStream multi = new MultiPartOutputStream(out);
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

        // If the request has a "Request-Range" header then we need to
        // send an old style multipart/x-byteranges Content-Type. This
        // keeps Netscape and acrobat happy. This is what Apache does.
        String ctp;
        if (request.getHeader(HttpHeader.REQUEST_RANGE.asString()) != null) {
            ctp = "multipart/x-byteranges; boundary=";
        } else {
            ctp = "multipart/byteranges; boundary=";
        }
        response.setContentType(ctp + multi.getBoundary());

        InputStream in = resource.getInputStream();
        long pos = 0;

        // calculate the content-length
        int length = 0;
        String[] header = new String[ranges.size()];
        for (int i = 0; i < ranges.size(); i++) {
            InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
            header[i] = ibr.toHeaderRangeString(content_length);
            length += ((i > 0) ? 2 : 0) + 2 + multi.getBoundary().length() + 2
                    + (mimetype == null ? 0 : HeaderFramework.CONTENT_TYPE.length() + 2 + mimetype.length()) + 2
                    + HeaderFramework.CONTENT_RANGE.length() + 2 + header[i].length() + 2 + 2
                    + (ibr.getLast(content_length) - ibr.getFirst(content_length)) + 1;
        }
        length += 2 + 2 + multi.getBoundary().length() + 2 + 2;
        response.setContentLength(length);

        for (int i = 0; i < ranges.size(); i++) {
            InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
            multi.startPart(mimetype, new String[] { HeaderFramework.CONTENT_RANGE + ": " + header[i] });

            long start = ibr.getFirst(content_length);
            long size = ibr.getSize(content_length);
            if (in != null) {
                // Handle non cached resource
                if (start < pos) {
                    in.close();
                    in = resource.getInputStream();
                    pos = 0;
                }
                if (pos < start) {
                    in.skip(start - pos);
                    pos = start;
                }

                FileUtils.copy(in, multi, size);
                pos += size;
            } else // Handle cached resource
            {
                (resource).writeTo(multi, start, size);
            }

        }
        if (in != null)
            in.close();
        multi.close();
    }
}

From source file:org.rhq.gui.content.ContentHTTPServlet.java

protected boolean writePackageVersionBits(HttpServletRequest request, HttpServletResponse response,
        PackageVersion pkgVer) {//from   ww  w  .j a v a 2s.  c  o  m
    //
    // Anaconda does a fetch with specific ranges so it can locate the header in a rpm.
    // Refer to anaconda source: yuminstall.py to see the details.
    // We will default to range values of [0 -> -1] which will allow non-range based fetches to work as usual
    //
    long startRange = getStartRange(request);
    long endRange = getEndRange(request);
    if (endRange < 0) {
        response.setContentType("application/x-rpm");
        response.setContentLength(pkgVer.getFileSize().intValue());
    } else {
        response.setContentType("application/octet-stream");
        log.debug("Range request: start = " + startRange + ", end = " + endRange);
        int contentLength = new Long(endRange).intValue() - new Long(startRange).intValue() + 1;
        log.debug("Setting contentLength = " + contentLength);
        response.setContentLength(contentLength);
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        String rangeHdr = "bytes=" + startRange + "-" + endRange + "/" + contentLength;
        response.setHeader("Content-Range", rangeHdr);
    }
    try {
        ServletOutputStream output = response.getOutputStream();
        contentSourceMgr.outputPackageVersionBits(pkgVer, output, startRange, endRange);
        output.flush();
        output.close();
    } catch (IllegalStateException e) {
        log.error(e);
        return false;
    } catch (IOException e) {
        log.error(e);
        return false;
    }
    return true;
}

From source file:org.gss_project.gss.server.rest.FilesHandler.java

/**
  * Serve the specified resource, optionally including the data content.
  */*from  w w  w . j a va2  s. com*/
  * @param req The servlet request we are processing
  * @param resp The servlet response we are creating
  * @param content Should the content be included?
  *
  * @exception IOException if an input/output error occurs
  * @exception ServletException if a servlet-specified error occurs
  * @throws RpcException
  * @throws InsufficientPermissionsException
  * @throws ObjectNotFoundException
  */
@Override
protected void serveResource(HttpServletRequest req, HttpServletResponse resp, boolean content)
        throws IOException, ServletException {
    boolean authDeferred = getAuthDeferred(req);
    String path = getInnerPath(req, PATH_FILES);
    if (path.equals(""))
        path = "/";
    try {
        path = URLDecoder.decode(path, "UTF-8");
    } catch (IllegalArgumentException e) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        return;
    }
    String progress = req.getParameter(PROGRESS_PARAMETER);

    if (logger.isDebugEnabled())
        if (content)
            logger.debug("Serving resource '" + path + "' headers and data");
        else
            logger.debug("Serving resource '" + path + "' headers only");

    User user = getUser(req);
    User owner = getOwner(req);
    boolean exists = true;
    Object resource = null;
    FileHeader file = null;
    Folder folder = null;
    try {
        resource = getService().getResourceAtPath(owner.getId(), path, false);
    } catch (ObjectNotFoundException e) {
        exists = false;
    } catch (RpcException e) {
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
        return;
    }

    if (!exists && authDeferred) {
        // We do not want to leak information if the request
        // was not authenticated.
        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
    }

    if (resource instanceof Folder)
        folder = (Folder) resource;
    else
        file = (FileHeader) resource; // Note that file will be null, if (!exists).

    // Now it's time to perform the deferred authentication check.
    // Since regular signature checking was already performed,
    // we need to check the read-all flag or the signature-in-parameters.
    if (authDeferred) {
        if (file != null && !file.isReadForAll() && content) {
            // Check for GET with the signature in the request parameters.
            String auth = req.getParameter(AUTHORIZATION_PARAMETER);
            String dateParam = req.getParameter(DATE_PARAMETER);
            if (auth == null || dateParam == null) {
                // Check for a valid authentication cookie.
                if (req.getCookies() != null) {
                    boolean found = false;
                    for (Cookie cookie : req.getCookies())
                        if (Login.AUTH_COOKIE.equals(cookie.getName())) {
                            String cookieauth = cookie.getValue();
                            int sepIndex = cookieauth.indexOf(Login.COOKIE_SEPARATOR);
                            if (sepIndex == -1) {
                                handleAuthFailure(req, resp);
                                return;
                            }
                            String username = URLDecoder.decode(cookieauth.substring(0, sepIndex), "US-ASCII");
                            user = null;
                            try {
                                user = getService().findUser(username);
                            } catch (RpcException e) {
                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                                return;
                            }
                            if (user == null) {
                                resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                                return;
                            }
                            req.setAttribute(USER_ATTRIBUTE, user);
                            String token = cookieauth.substring(sepIndex + 1);
                            if (user.getAuthToken() == null) {
                                resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                                return;
                            }
                            if (!Arrays.equals(user.getAuthToken(), Base64.decodeBase64(token))) {
                                resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                                return;
                            }
                            found = true;
                            break;
                        }
                    if (!found) {
                        handleAuthFailure(req, resp);
                        return;
                    }
                } else {
                    handleAuthFailure(req, resp);
                    return;
                }
            } else {
                long timestamp;
                try {
                    timestamp = DateUtil.parseDate(dateParam).getTime();
                } catch (DateParseException e) {
                    resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
                    return;
                }

                // Fetch the Authorization parameter and find the user specified in it.
                String[] authParts = auth.split(" ");
                if (authParts.length != 2) {
                    resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                    return;
                }
                String username = authParts[0];
                String signature = authParts[1];
                user = null;
                try {
                    user = getService().findUser(username);
                } catch (RpcException e) {
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                    return;
                }
                if (user == null) {
                    resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                    return;
                }
                req.setAttribute(USER_ATTRIBUTE, user);

                // Remove the servlet path from the request URI.
                String p = req.getRequestURI();
                String servletPath = req.getContextPath() + req.getServletPath();
                p = p.substring(servletPath.length());
                // Validate the signature in the Authorization parameter.
                String data = req.getMethod() + dateParam + p;
                if (!isSignatureValid(signature, user, data)) {
                    resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                    return;
                }
            }
        } else if (folder != null && folder.isReadForAll() || file != null && file.isReadForAll()) {
            //This case refers to a folder or file with public privileges
            //For a read-for-all folder request, pretend the owner is making it.
            user = owner;
            req.setAttribute(USER_ATTRIBUTE, user);
        } else if (folder != null && !folder.isReadForAll()) {
            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        } else {
            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
    }
    // If the resource is not a collection, and the resource path
    // ends with "/" or "\", return NOT FOUND.
    if (folder == null)
        if (path.endsWith("/") || path.endsWith("\\")) {
            resp.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI());
            return;
        }

    // Workaround for IE's broken caching behavior.
    if (folder != null)
        resp.setHeader("Expires", "-1");

    // A request for upload progress.
    if (progress != null && content) {
        serveProgress(req, resp, progress, user, file);
        return;
    }

    // Fetch the version to retrieve, if specified.
    String verStr = req.getParameter(VERSION_PARAM);
    int version = 0;
    FileBody oldBody = null;
    if (verStr != null && file != null)
        try {
            version = Integer.valueOf(verStr);
        } catch (NumberFormatException e) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, req.getRequestURI());
            return;
        }
    if (version > 0)
        try {
            oldBody = getService().getFileVersion(user.getId(), file.getId(), version);
        } catch (RpcException e) {
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
            return;
        } catch (ObjectNotFoundException e) {
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        } catch (InsufficientPermissionsException e) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }

    // Check if the conditions specified in the optional If headers are
    // satisfied. Doing this for folders would require recursive checking
    // for all of their children, which in turn would defy the purpose of
    // the optimization.
    if (folder == null) {
        // Checking If headers.
        if (!checkIfHeaders(req, resp, file, oldBody))
            return;
    } else if (!checkIfModifiedSince(req, resp, folder))
        return;

    // Find content type.
    String contentType = null;
    boolean isContentHtml = false;
    boolean expectJSON = false;

    if (file != null) {
        contentType = version > 0 ? oldBody.getMimeType() : file.getCurrentBody().getMimeType();
        if (contentType == null) {
            contentType = context.getMimeType(file.getName());
            file.getCurrentBody().setMimeType(contentType);
        }
    } else { // folder != null
        String accept = req.getHeader("Accept");
        // The order in this conditional pessimizes the common API case,
        // but is important for backwards compatibility with existing
        // clients who send no accept header and expect a JSON response.
        if (accept != null && accept.contains("text/html")) {
            contentType = "text/html;charset=UTF-8";
            isContentHtml = true;
            //this is the case when clients send the appropriate headers, the contentType is "text/html"
            //and expect a JSON response. The above check applies to FireGSS client
            expectJSON = !authDeferred ? true : false;
        } else if (authDeferred && req.getMethod().equals(METHOD_GET)) {
            contentType = "text/html;charset=UTF-8";
            isContentHtml = true;
            expectJSON = false;
        } else {
            contentType = "application/json;charset=UTF-8";
            expectJSON = true;
        }
    }

    ArrayList ranges = null;
    long contentLength = -1L;

    if (file != null) {
        // Parse range specifier.
        ranges = parseRange(req, resp, file, oldBody);
        // ETag header
        resp.setHeader("ETag", getETag(file, oldBody));
        // Last-Modified header.
        String lastModified = oldBody == null ? getLastModifiedHttp(file.getAuditInfo())
                : getLastModifiedHttp(oldBody.getAuditInfo());
        resp.setHeader("Last-Modified", lastModified);
        // X-GSS-Metadata header.
        try {
            resp.setHeader("X-GSS-Metadata", renderJson(user, file, oldBody));
        } catch (InsufficientPermissionsException e) {
            resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }
        // Get content length.
        contentLength = version > 0 ? oldBody.getFileSize() : file.getCurrentBody().getFileSize();
        // Special case for zero length files, which would cause a
        // (silent) ISE when setting the output buffer size.
        if (contentLength == 0L)
            content = false;
    } else
        // Set the folder X-GSS-Metadata header.
        try {
            resp.setHeader("X-GSS-Metadata", renderJsonMetadata(user, folder));
        } catch (InsufficientPermissionsException e) {
            resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }

    ServletOutputStream ostream = null;
    PrintWriter writer = null;

    if (content)
        try {
            ostream = resp.getOutputStream();
        } catch (IllegalStateException e) {
            // If it fails, we try to get a Writer instead if we're
            // trying to serve a text file
            if (contentType == null || contentType.startsWith("text") || contentType.endsWith("xml"))
                writer = resp.getWriter();
            else
                throw e;
        }
    if (folder != null || (ranges == null || ranges.isEmpty()) && req.getHeader("Range") == null
            || ranges == FULL) {
        // Set the appropriate output headers
        if (contentType != null) {
            if (logger.isDebugEnabled())
                logger.debug("contentType='" + contentType + "'");
            resp.setContentType(contentType);
        }
        if (file != null && contentLength >= 0) {
            if (logger.isDebugEnabled())
                logger.debug("contentLength=" + contentLength);
            if (contentLength < Integer.MAX_VALUE)
                resp.setContentLength((int) contentLength);

            else
                // Set the content-length as String to be able to use a long
                resp.setHeader("content-length", "" + contentLength);
        }

        InputStream renderResult = null;
        String relativePath = getRelativePath(req);
        String contextPath = req.getContextPath();
        String servletPath = req.getServletPath();
        String contextServletPath = contextPath + servletPath;
        if (folder != null && content)
            // Serve the directory browser for a public folder
            if (isContentHtml && !expectJSON) {
                try {
                    folder = getService().expandFolder(folder);
                } catch (ObjectNotFoundException e) {
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                    return;
                } catch (RpcException e) {
                    //We send 500 instead of 404 because this folder has been loaded before in this method and it is
                    //impossible to not be found now
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
                    return;
                }
                renderResult = renderHtml(contextServletPath, relativePath, folder, user);
            }
            // Serve the directory for an ordinary folder or for fireGSS client
            else
                try {
                    renderResult = renderJson(user, folder);
                } catch (InsufficientPermissionsException e) {
                    resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                    return;
                }

        // Copy the input stream to our output stream (if requested)
        if (content) {
            try {
                resp.setBufferSize(output);
            } catch (IllegalStateException e) {
                // Silent catch
            }
            try {
                if (file != null)
                    if (needsContentDisposition(req))
                        resp.setHeader("Content-Disposition",
                                "attachment; filename*=UTF-8''" + getDispositionFilename(file));
                    else
                        resp.setHeader("Content-Disposition",
                                "inline; filename*=UTF-8''" + getDispositionFilename(file));
                if (ostream != null)
                    copy(file, renderResult, ostream, req, oldBody);
                else
                    copy(file, renderResult, writer, req, oldBody);
                if (file != null)
                    updateAccounting(owner, new Date(), contentLength);
            } catch (ObjectNotFoundException e) {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            } catch (InsufficientPermissionsException e) {
                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                return;
            } catch (RpcException e) {
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
            }
        }
    } else {
        if (ranges == null || ranges.isEmpty())
            return;
        // Partial content response.
        resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

        if (ranges.size() == 1) {
            Range range = (Range) ranges.get(0);
            resp.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length);
            long length = range.end - range.start + 1;
            if (length < Integer.MAX_VALUE)
                resp.setContentLength((int) length);
            else
                // Set the content-length as String to be able to use a long
                resp.setHeader("content-length", "" + length);

            if (contentType != null) {
                if (logger.isDebugEnabled())
                    logger.debug("contentType='" + contentType + "'");
                resp.setContentType(contentType);
            }

            if (content) {
                try {
                    resp.setBufferSize(output);
                } catch (IllegalStateException e) {
                    // Silent catch
                }
                try {
                    if (ostream != null)
                        copy(file, ostream, range, req, oldBody);
                    else
                        copy(file, writer, range, req, oldBody);
                    updateAccounting(owner, new Date(), contentLength);
                } catch (ObjectNotFoundException e) {
                    resp.sendError(HttpServletResponse.SC_NOT_FOUND);
                    return;
                } catch (InsufficientPermissionsException e) {
                    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                    return;
                } catch (RpcException e) {
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    return;
                }
            }
        } else {
            resp.setContentType("multipart/byteranges; boundary=" + mimeSeparation);
            if (content) {
                try {
                    resp.setBufferSize(output);
                } catch (IllegalStateException e) {
                    // Silent catch
                }
                try {
                    if (ostream != null)
                        copy(file, ostream, ranges.iterator(), contentType, req, oldBody);
                    else
                        copy(file, writer, ranges.iterator(), contentType, req, oldBody);
                    updateAccounting(owner, new Date(), contentLength);
                } catch (ObjectNotFoundException e) {
                    resp.sendError(HttpServletResponse.SC_NOT_FOUND);
                    return;
                } catch (InsufficientPermissionsException e) {
                    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                    return;
                } catch (RpcException e) {
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    return;
                }
            }
        }
    }
}

From source file:com.redhat.rhn.frontend.action.common.DownloadFile.java

private StreamInfo manualServeByteRange(HttpServletRequest request, HttpServletResponse response,
        String diskPath, String range) {

    // bytes=440-25183
    Pattern rangePattern = Pattern.compile("bytes=(\\d*)-(\\d*)");
    Matcher rangeMatcher = rangePattern.matcher(range);

    if (!rangeMatcher.matches()) {
        // this will fail
        rangeMatcher.group(1);/*from  w  w w. ja  v  a  2s  . co  m*/
    }

    long start, end;
    if (StringUtils.isEmpty(rangeMatcher.group(1))) {
        start = 0;
    } else {
        start = Long.valueOf(rangeMatcher.group(1));
    }
    File actualFile = new File(diskPath);
    long totalSize = actualFile.length();
    if (StringUtils.isEmpty(rangeMatcher.group(2))) {
        end = totalSize;
    } else {
        end = Long.valueOf(rangeMatcher.group(2)).longValue();
    }
    if (log.isDebugEnabled()) {
        log.debug("manualServeByteRange Start    : " + start);
        log.debug("manualServeByteRange End      : " + end);
    }
    long size = end - start + 1;

    if (log.isDebugEnabled()) {
        log.debug("manualServeByteRange totalsize: " + totalSize);
    }

    if (size <= 0) {
        return getStreamForBinary(diskPath);
    }
    setBinaryContentInfo(response, (int) size);
    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    Date mtime = new Date(actualFile.lastModified());
    // "EEE, dd MMM yyyy HH:mm:ss zzz";
    SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
    formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
    String fdate = formatter.format(mtime);
    response.addHeader("last-modified", fdate);
    response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + totalSize);
    response.addHeader("Accept-Ranges", "bytes");
    if (log.isDebugEnabled()) {
        log.debug("Added header last-modified: " + fdate);
        log.debug("Added header Content-Length: " + String.valueOf(size));
        log.debug("Added header Content-Range: " + "bytes " + start + "-" + end + "/" + totalSize);
        log.debug("Added header Accept-Ranges: bytes");
    }
    // gotta make sure it is end + 1
    byte[] chunk = FileUtils.readByteArrayFromFile(actualFile, start, end + 1);
    if (log.isDebugEnabled()) {
        log.debug("chunk size: " + chunk.length);
        log.debug("read chunk into byte array.  returning ByteArrayStreamInfo");
    }
    ByteArrayStreamInfo stream = new ByteArrayStreamInfo(CONTENT_TYPE_OCTET_STREAM, chunk);
    return stream;
}

From source file:de.mendelson.comm.as2.send.MessageHttpUploader.java

/**Uploads the data, returns the HTTP result code*/
public int performUpload(HttpConnectionParameter connectionParameter, AS2Message message, Partner sender,
        Partner receiver, URL receiptURL) {
    String ediintFeatures = "multiple-attachments, CEM";
    //set the http connection/routing/protocol parameter
    HttpParams httpParams = new BasicHttpParams();
    if (connectionParameter.getConnectionTimeoutMillis() != -1) {
        HttpConnectionParams.setConnectionTimeout(httpParams, connectionParameter.getConnectionTimeoutMillis());
    }/*from w w w. j  ava2  s  .  co  m*/
    if (connectionParameter.getSoTimeoutMillis() != -1) {
        HttpConnectionParams.setSoTimeout(httpParams, connectionParameter.getSoTimeoutMillis());
    }
    HttpConnectionParams.setStaleCheckingEnabled(httpParams, connectionParameter.isStaleConnectionCheck());
    if (connectionParameter.getHttpProtocolVersion() == null) {
        //default settings: HTTP 1.1
        HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
    } else if (connectionParameter.getHttpProtocolVersion().equals(HttpConnectionParameter.HTTP_1_0)) {
        HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_0);
    } else if (connectionParameter.getHttpProtocolVersion().equals(HttpConnectionParameter.HTTP_1_1)) {
        HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
    }
    HttpProtocolParams.setUseExpectContinue(httpParams, connectionParameter.isUseExpectContinue());
    HttpProtocolParams.setUserAgent(httpParams, connectionParameter.getUserAgent());
    if (connectionParameter.getLocalAddress() != null) {
        ConnRouteParams.setLocalAddress(httpParams, connectionParameter.getLocalAddress());
    }
    int status = -1;
    HttpPost filePost = null;
    DefaultHttpClient httpClient = null;
    try {
        ClientConnectionManager clientConnectionManager = this.createClientConnectionManager(httpParams);
        httpClient = new DefaultHttpClient(clientConnectionManager, httpParams);
        //some ssl implementations have problems with a session/connection reuse
        httpClient.setReuseStrategy(new NoConnectionReuseStrategy());
        //disable SSL hostname verification. Do not confuse this with SSL trust verification!
        SSLSocketFactory sslFactory = (SSLSocketFactory) httpClient.getConnectionManager().getSchemeRegistry()
                .get("https").getSocketFactory();
        sslFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        //determine the receipt URL if it is not set
        if (receiptURL == null) {
            //async MDN requested?
            if (message.isMDN()) {
                if (this.runtimeConnection == null) {
                    throw new IllegalArgumentException(
                            "MessageHTTPUploader.performUpload(): A MDN receipt URL is not set, unable to determine where to send the MDN");
                }
                MessageAccessDB messageAccess = new MessageAccessDB(this.configConnection,
                        this.runtimeConnection);
                AS2MessageInfo relatedMessageInfo = messageAccess
                        .getLastMessageEntry(((AS2MDNInfo) message.getAS2Info()).getRelatedMessageId());
                receiptURL = new URL(relatedMessageInfo.getAsyncMDNURL());
            } else {
                receiptURL = new URL(receiver.getURL());
            }
        }
        filePost = new HttpPost(receiptURL.toExternalForm());
        filePost.addHeader("as2-version", "1.2");
        filePost.addHeader("ediint-features", ediintFeatures);
        filePost.addHeader("mime-version", "1.0");
        filePost.addHeader("recipient-address", receiptURL.toExternalForm());
        filePost.addHeader("message-id", "<" + message.getAS2Info().getMessageId() + ">");
        filePost.addHeader("as2-from", AS2Message.escapeFromToHeader(sender.getAS2Identification()));
        filePost.addHeader("as2-to", AS2Message.escapeFromToHeader(receiver.getAS2Identification()));
        String originalFilename = null;
        if (message.getPayloads() != null && message.getPayloads().size() > 0) {
            originalFilename = message.getPayloads().get(0).getOriginalFilename();
        }
        if (originalFilename != null) {
            String subject = this.replace(message.getAS2Info().getSubject(), "${filename}", originalFilename);
            filePost.addHeader("subject", subject);
            //update the message infos subject with the actual content
            if (!message.isMDN()) {
                ((AS2MessageInfo) message.getAS2Info()).setSubject(subject);
                //refresh this in the database if it is requested
                if (this.runtimeConnection != null) {
                    MessageAccessDB access = new MessageAccessDB(this.configConnection, this.runtimeConnection);
                    access.updateSubject((AS2MessageInfo) message.getAS2Info());
                }
            }
        } else {
            filePost.addHeader("subject", message.getAS2Info().getSubject());
        }
        filePost.addHeader("from", sender.getEmail());
        filePost.addHeader("connection", "close, TE");
        //the data header must be always in english locale else there would be special
        //french characters (e.g. 13 dc. 2011 16:28:56 CET) which is not allowed after 
        //RFC 4130           
        DateFormat format = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss zz", Locale.US);
        filePost.addHeader("date", format.format(new Date()));
        String contentType = null;
        if (message.getAS2Info().getEncryptionType() != AS2Message.ENCRYPTION_NONE) {
            contentType = "application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m";
        } else {
            contentType = message.getContentType();
        }
        filePost.addHeader("content-type", contentType);
        //MDN header, this is always the way for async MDNs
        if (message.isMDN()) {
            if (this.logger != null) {
                this.logger.log(Level.INFO,
                        this.rb.getResourceString("sending.mdn.async",
                                new Object[] { message.getAS2Info().getMessageId(), receiptURL }),
                        message.getAS2Info());
            }
            filePost.addHeader("server", message.getAS2Info().getUserAgent());
        } else {
            AS2MessageInfo messageInfo = (AS2MessageInfo) message.getAS2Info();
            //outbound AS2/CEM message
            if (messageInfo.requestsSyncMDN()) {
                if (this.logger != null) {
                    if (messageInfo.getMessageType() == AS2Message.MESSAGETYPE_CEM) {
                        this.logger.log(Level.INFO,
                                this.rb.getResourceString("sending.cem.sync",
                                        new Object[] { messageInfo.getMessageId(), receiver.getURL() }),
                                messageInfo);
                    } else if (messageInfo.getMessageType() == AS2Message.MESSAGETYPE_AS2) {
                        this.logger.log(Level.INFO,
                                this.rb.getResourceString("sending.msg.sync",
                                        new Object[] { messageInfo.getMessageId(), receiver.getURL() }),
                                messageInfo);
                    }
                }
            } else {
                //Message with ASYNC MDN request
                if (this.logger != null) {
                    if (messageInfo.getMessageType() == AS2Message.MESSAGETYPE_CEM) {
                        this.logger.log(Level.INFO,
                                this.rb.getResourceString("sending.cem.async", new Object[] {
                                        messageInfo.getMessageId(), receiver.getURL(), sender.getMdnURL() }),
                                messageInfo);
                    } else if (messageInfo.getMessageType() == AS2Message.MESSAGETYPE_AS2) {
                        this.logger.log(Level.INFO,
                                this.rb.getResourceString("sending.msg.async", new Object[] {
                                        messageInfo.getMessageId(), receiver.getURL(), sender.getMdnURL() }),
                                messageInfo);
                    }
                }
                //The following header indicates that this requests an asnc MDN.
                //When the header "receipt-delivery-option" is present,
                //the header "disposition-notification-to" serves as a request
                //for an asynchronous MDN.
                //The header "receipt-delivery-option" must always be accompanied by
                //the header "disposition-notification-to".
                //When the header "receipt-delivery-option" is not present and the header
                //"disposition-notification-to" is present, the header "disposition-notification-to"
                //serves as a request for a synchronous MDN.
                filePost.addHeader("receipt-delivery-option", sender.getMdnURL());
            }
            filePost.addHeader("disposition-notification-to", sender.getMdnURL());
            //request a signed MDN if this is set up in the partner configuration
            if (receiver.isSignedMDN()) {
                filePost.addHeader("disposition-notification-options",
                        messageInfo.getDispositionNotificationOptions().getHeaderValue());
            }
            if (messageInfo.getSignType() != AS2Message.SIGNATURE_NONE) {
                filePost.addHeader("content-disposition", "attachment; filename=\"smime.p7m\"");
            } else if (messageInfo.getSignType() == AS2Message.SIGNATURE_NONE
                    && message.getAS2Info().getSignType() == AS2Message.ENCRYPTION_NONE) {
                filePost.addHeader("content-disposition",
                        "attachment; filename=\"" + message.getPayload(0).getOriginalFilename() + "\"");
            }
        }
        int port = receiptURL.getPort();
        if (port == -1) {
            port = receiptURL.getDefaultPort();
        }
        filePost.addHeader("host", receiptURL.getHost() + ":" + port);
        InputStream rawDataInputStream = message.getRawDataInputStream();
        InputStreamEntity postEntity = new InputStreamEntity(rawDataInputStream, message.getRawDataSize());
        postEntity.setContentType(contentType);
        filePost.setEntity(postEntity);
        if (connectionParameter.getProxy() != null) {
            this.setProxyToConnection(httpClient, message, connectionParameter.getProxy());
        }
        this.setHTTPAuthentication(httpClient, receiver, message.getAS2Info().isMDN());
        this.updateUploadHttpHeader(filePost, receiver);
        HttpHost targetHost = new HttpHost(receiptURL.getHost(), receiptURL.getPort(),
                receiptURL.getProtocol());
        BasicHttpContext localcontext = new BasicHttpContext();
        // Generate BASIC scheme object and stick it to the local
        // execution context. Without this a HTTP authentication will not be sent
        BasicScheme basicAuth = new BasicScheme();
        localcontext.setAttribute("preemptive-auth", basicAuth);
        HttpResponse httpResponse = httpClient.execute(targetHost, filePost, localcontext);
        rawDataInputStream.close();
        this.responseData = this.readEntityData(httpResponse);
        if (httpResponse != null) {
            this.responseStatusLine = httpResponse.getStatusLine();
            status = this.responseStatusLine.getStatusCode();
            this.responseHeader = httpResponse.getAllHeaders();
        }
        for (Header singleHeader : filePost.getAllHeaders()) {
            if (singleHeader.getValue() != null) {
                this.requestHeader.setProperty(singleHeader.getName(), singleHeader.getValue());
            }
        }
        //accept all 2xx answers
        //SC_ACCEPTED Status code (202) indicating that a request was accepted for processing, but was not completed.
        //SC_CREATED  Status code (201) indicating the request succeeded and created a new resource on the server.
        //SC_NO_CONTENT Status code (204) indicating that the request succeeded but that there was no new information to return.
        //SC_NON_AUTHORITATIVE_INFORMATION Status code (203) indicating that the meta information presented by the client did not originate from the server.
        //SC_OK Status code (200) indicating the request succeeded normally.
        //SC_RESET_CONTENT Status code (205) indicating that the agent SHOULD reset the document view which caused the request to be sent.
        //SC_PARTIAL_CONTENT Status code (206) indicating that the server has fulfilled the partial GET request for the resource.
        if (status != HttpServletResponse.SC_OK && status != HttpServletResponse.SC_ACCEPTED
                && status != HttpServletResponse.SC_CREATED && status != HttpServletResponse.SC_NO_CONTENT
                && status != HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION
                && status != HttpServletResponse.SC_RESET_CONTENT
                && status != HttpServletResponse.SC_PARTIAL_CONTENT) {
            if (this.logger != null) {
                this.logger
                        .severe(this.rb.getResourceString("error.httpupload",
                                new Object[] { message.getAS2Info().getMessageId(),
                                        URLDecoder.decode(
                                                this.responseStatusLine == null ? ""
                                                        : this.responseStatusLine.getReasonPhrase(),
                                                "UTF-8") }));
            }
        }
    } catch (Exception ex) {
        if (this.logger != null) {
            StringBuilder errorMessage = new StringBuilder(message.getAS2Info().getMessageId());
            errorMessage.append(": MessageHTTPUploader.performUpload: [");
            errorMessage.append(ex.getClass().getSimpleName());
            errorMessage.append("]");
            if (ex.getMessage() != null) {
                errorMessage.append(": ").append(ex.getMessage());
            }
            this.logger.log(Level.SEVERE, errorMessage.toString(), message.getAS2Info());
        }
    } finally {
        if (httpClient != null && httpClient.getConnectionManager() != null) {
            //shutdown the HTTPClient to release the resources
            httpClient.getConnectionManager().shutdown();
        }
    }
    return (status);
}