Uploaded image for project: 'Imaging'
  1. Imaging
  2. MGNLIMG-317

Incorrect Content-Range Header when using ranged request

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 3.5.6, 3.5.7, 3.5.8
    • None
    • None
    • Magnolia Version 6.2.27 up to 6.2.35
      Imaging module 3.5.6 up to 3.5.8, possibly earlier version as well

    Description

      While trying to setup Azure Front Door to serve cached images from imaging module we noticed that FD was unable to serve images served under /.imaging path in Magnolia. The root cause of that was identified as an incorrect Content-Range header value. Observe the faulty value below (Note: asset content length in the example below was ~65000)

      Steps to reproduce

      1. Issue a request to /.imaging using Range header
      2. Observe invalid Content-Range response header

       

      > GET /.imaging/focalpoint/_WIDTH_x_HEIGHT_/{{YOUR_DAM_JCR_ASSET}} HTTP/1.1
      > Host: localhost:8080
      > User-Agent: curl/7.84.0
      > Accept: */*
      > Range: bytes=0-1000000
      
      * Mark bundle as not supporting multiuse
      < HTTP/1.1 206
      < X-Magnolia-Registration: Registered
      < Cache-Control: max-age=600, public
      < Expires: Wed, 05 Jul 2023 11:17:36 GMT
      < ETag: 0CF063449C58CAE7CD3D4E28E1BAAAA1C265B2A6
      < Accept-Ranges: bytes
      < Content-Range: bytes 0-1000000/2147483647
      < Content-Type: image/webp;charset=UTF-8
      < Transfer-Encoding: chunked
      < Date: Wed, 05 Jul 2023 11:07:37 GMT

       

      Expected results

      Observe the results after implementation of workaround

       

      > GET /.imaging/focalpoint/_WIDTH_x_HEIGHT_/dam/{{YOUR_DAM_JCR_ASSET}} HTTP/1.1
      > Host: localhost:8080
      > User-Agent: curl/7.84.0
      > Accept: */*
      > Range: bytes=0-1000000
      
      * Mark bundle as not supporting multiuse
      < HTTP/1.1 206
      < X-Magnolia-Registration: Registered
      < Cache-Control: max-age=600, public
      < Expires: Wed, 05 Jul 2023 11:20:31 GMT
      < ETag: A583335CC1450A3D131BD8FE2FF9BB4599268724
      < Accept-Ranges: bytes
      < Content-Range: bytes 0-64065/64066
      < Content-Type: image/webp;charset=UTF-8
      < Transfer-Encoding: chunked
      < Date: Wed, 05 Jul 2023 11:10:31 GMT 

       

      Actual results

      You can find an output from the curl command under Steps To Reproduce

      Workaround

      There are two possible solutions for this.

      1. Disabling ranged requests
        Add the configuration as shown on screenshot under config workspace @ /server/filters/range
        Note that this will disable ranged requests entirely severely reducing the efficiency of Azure FD when delivering large files.
      2. Manually setting Content-Range headers on response.
        You need a custom ServletImageResponse that can set content length on the response. Provide your own ImagingServlet implementation that uses your custom ServletImageResponse. Additionally you need to provide custom AbstractImageStreamer implementations as below:
        public class CustomCachingImageStreamer<P> extends CachingImageStreamer<P> {
            public CustomCachingImageStreamer(Session session, CachingStrategy<P> cachingStrategy, ImageStreamer<P> delegate, SystemContext systemContext) {
                super(session, cachingStrategy, delegate, systemContext);
            }
        
            @Override
            protected void serve(Property binary, ImageResponse imageResponse) throws IOException {
                final InputStream in;
                try {
                    in = binary.getBinary().getStream();
                } catch (RepositoryException e) {
                    throw new IllegalStateException("Can't get InputStream from " + binary);
                }
                final String contentType;
                try {
                    contentType = binary.getParent().getProperty(JcrConstants.JCR_MIMETYPE).getString();
                } catch (RepositoryException e) {
                    throw new IllegalStateException("Can't get content-type from " + binary);
                }
                imageResponse.setMediaType(MediaType.parse(contentType));
        
        //--- START OF CHANGE
                ContentLengthImagingServletResponse castImageResponse = (ContentLengthImagingServletResponse) imageResponse;
                try {
                    castImageResponse.setContentLength((int) binary.getLength());
                } catch (RepositoryException e) {
                    throw new IllegalStateException("Can't get content-length from " + binary);
                }
        // --- END OF CHANGE
        
                final OutputStream out = imageResponse.getOutputStream();
                IOUtils.copy(in, out);
                IOUtils.closeQuietly(in);
            }
        } 

      Development notes

      The root cause of the issue seems to be that no length is set on the ServletImageResponse. This is going through the info.magnolia.cms.filters.RangeSupportFilter that sets the default value of Content-Range header because range values are not specifically provided in case of the imaging servlet. Have a look at RangeSupportFilter#processRange()

      Checklists

        Acceptance criteria

        Attachments

          Activity

            People

              Unassigned Unassigned
              tkoktsidis Theocharis Koktsidis
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Checklists

                  Bug DoR
                  Task DoD