Class StreamedChunk


  • public class StreamedChunk
    extends Object
    Supports streamed uploads including where the stream is made up of partial body parts. The behaviour is documented here https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support, adding the ability to define a body part with a Content-Range header on the part. Since the body parts are streamed there are some restrictions. If the length of a body part is missing from either the Content-Range header or a Content-Length header in the Part, then the length of the part is assumed to be the rest of the body to make the total length of the upload that specified in earlier Content-Range headers or a @Length property. When using only Content-Range headers (see the HTTP 1.1 spec) the Content-Range header must be complete and applied to the Part of the body. The length of the full file must be specified and be the same on all body parts, and the body parts must be sent in order. This is a restriction of the Sling Chunked File Upload protocol. When the total uploaded equals the file length the chunked uploads are processed to generate the final upload. When using request parameters, the most recent request parameters are used for @Completed, @Offset and @Length. When using request parameters if the Content-Length header is missing from the body Part, then the Body part is assumed to be the final body part. Then the total uploaded equals the value of the @Length parameter or a @Completed parameter is present, then the body parts are joined into a single body part. Consolidating body parts will cause all body parts to be read from the DS, which will incure 3x the IO of a non body part or chunked upload. For FS DS the IO may be from OS level disk cache. For other styles of DS the IO may consume more resources. Chunked or Body part uploads are not as efficient as whole body uploads and should be avoided wherever possible. This could be avoided if Oak would expose a seekable OutputStream, or allow writes to Binaries to specify and offset.
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  StreamedChunk.ContentRange
      Parses Content-Range headers according to spec https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html section 14.16 Content-Range = "Content-Range" ":" content-range-spec content-range-spec = byte-content-range-spec byte-content-range-spec = bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" instance-length = 1*DIGIT eg bytes 0-1233/1234 bytes 500-1233/1234 bytes 500-1233/* According to https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.12 "bytes" is the only valid range unit.
    • Constructor Summary

      Constructors 
      Constructor Description
      StreamedChunk​(javax.servlet.http.Part part, Map<String,​List<String>> formFields, javax.servlet.ServletContext servletContext)
      Construct a chunk from the part and form fields.
    • Constructor Detail

      • StreamedChunk

        public StreamedChunk​(javax.servlet.http.Part part,
                             Map<String,​List<String>> formFields,
                             javax.servlet.ServletContext servletContext)
        Construct a chunk from the part and form fields. Once constructed it is immutable exposing a store method to store the chunk. If the part does not represent a chunk then the class behaves as if the chunk is a upload of 1 chunk (ie the whole file).
        Parameters:
        part - the current part, not read other than headers.
        formFields - form fields encountered in teh request stream prior to this part.
        servletContext - the current servlet context needed to resolve mimetypes.
    • Method Detail

      • store

        public org.apache.sling.api.resource.Resource store​(org.apache.sling.api.resource.Resource fileResource,
                                                            List<Modification> changes)
                                                     throws org.apache.sling.api.resource.PersistenceException
        Store the chunk in a file resource under a jcr:content sub node. The method does not commit the resource resolver. The caller must perform the commit. If the stream is a stream of body parts and the parts are complete, the store operation will commit the body part but leave the consolitation of all parts to be committed by the caller. ie, always call resourceResolver.commit() after calling this method.
        Parameters:
        fileResource - the file request.
        changes - changes that were made.
        Returns:
        the jcr:content sub node.
        Throws:
        org.apache.sling.api.resource.PersistenceException - in case of persistence issues