List of usage examples for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT
int SC_PARTIAL_CONTENT
To view the source code for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT.
Click Source Link
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); }