incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling > Chunked File Upload Support
Date Mon, 06 May 2013 15:59:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=SLING&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support">Chunked File Upload Support</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~shgupta">Shashank Gupta</a>
    </h4>
        <br/>
                         <h4>Changes (30)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h4. Chunk upload request <br></td></tr>
            <tr><td class="diff-changed-lines" >Client uses POST method to parent path to upload binary chunk of file. <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">Client</span> <span class="diff-added-words"style="background-color: #dfd;">Sling client</span> passes $filename@Offset and $filename@Length as multipart request parameters. &quot;Offset&quot; indicate chunk&#39;s data offset in complete file. &quot;Length&quot; is optional parameter and indicates length of complete file. If &quot;Length&quot; parameter is known, Sling automatically calculates if request is last chunk request and according stitches all chunks and store it into final destination. <br></td></tr>
            <tr><td class="diff-unchanged" >\[request\] <br>{code:title= First/Intermediate chunk upload request} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>\[response\] <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The response shows that chunk is stored within the actual path in sling:chunkMixin node type <br></td></tr>
            <tr><td class="diff-unchanged" >{code:title= Chunk upload response} <br>HTTP/1.1 200 OK <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >&lt;/html&gt; <br>{code} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The response shows that chunk is stored in tmp location. *The location tag contains unique chunk upload id which need to be passed on subsequent request.* <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h4. Intermediate chunk upload  <br>Client require to additionally  pass chunk upload id.  <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h4. Chunk Upload in streaming use case <br></td></tr>
            <tr><td class="diff-unchanged" >\[request\] <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{code:title= Intermediate chunk upload request} <br>POST /content/dam HTTP/1.1 <br>Authorization: Basic YWRtaW46YWRtaW4= <br>Transfer-Encoding: chunked <br>Content-Type: multipart/form-data; boundary=F1MYdmO-MYq-wLW2P2tWIu-7KUH3-r <br>Connection: Keep-Alive <br>User-Agent: Apache-HttpClient/4.1 (java 1.5) <br>Host: localhost:4502 <br> <br>--F1MYdmO-MYq-wLW2P2tWIu-7KUH3-r <br>Content-Disposition: form-data; name=&quot;:chunkNumber&quot; <br>Content-Type: text/plain; charset=UTF-8 <br>Content-Transfer-Encoding: 8bit <br> <br>3 <br>--F1MYdmO-MYq-wLW2P2tWIu-7KUH3-r <br>Content-Disposition: form-data; name=&quot;:chunkUploadId&quot; <br>Content-Type: text/plain; charset=UTF-8 <br>Content-Transfer-Encoding: 8bit <br> <br>/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08 <br>--F1MYdmO-MYq-wLW2P2tWIu-7KUH3-r <br>Content-Disposition: form-data; name=&quot;*&quot;; filename=&quot;catalog.pdf&quot; <br>Content-Type: application/octet-stream <br>Content-Transfer-Encoding: binary <br> <br>$binarydata <br>{code} <br> <br>\[response\] <br>{code:title= Intermediate chunk upload response} <br>HTTP/1.1 200 OK <br>Connection: Keep-Alive <br>Server: Day-Servlet-Engine/4.1.42 <br>Content-Type: text/html;charset=UTF-8 <br>Date: Thu, 28 Feb 2013 14:14:25 GMT <br>Transfer-Encoding: chunked <br> <br>&lt;html&gt; <br>&lt;head&gt; <br>    &lt;title&gt;Content modified /tmp/sling/chunks&lt;/title&gt; <br>&lt;/head&gt; <br>    &lt;body&gt; <br>    &lt;h1&gt;Content modified /tmp/sling/chunks&lt;/h1&gt; <br>    &lt;table&gt; <br>        &lt;tbody&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Status&lt;/td&gt; <br>                &lt;td&gt;&lt;div id=&quot;Status&quot;&gt;200&lt;/div&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Message&lt;/td&gt; <br>                &lt;td&gt;&lt;div id=&quot;Message&quot;&gt;OK&lt;/div&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Location&lt;/td&gt; <br>                &lt;td&gt;&lt;a href=&quot;/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&quot; id=&quot;Location&quot;&gt;/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&lt;/a&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Parent Location&lt;/td&gt; <br>                &lt;td&gt;&lt;a href=&quot;/tmp/sling/chunks&quot; id=&quot;ParentLocation&quot;&gt;/tmp/sling/chunks&lt;/a&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Path&lt;/td&gt; <br>                &lt;td&gt;&lt;div id=&quot;Path&quot;&gt;/tmp/sling/chunks&lt;/div&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Referer&lt;/td&gt; <br>                &lt;td&gt;&lt;a href=&quot;&quot; id=&quot;Referer&quot;&gt;&lt;/a&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;ChangeLog&lt;/td&gt; <br>                &lt;td&gt;&lt;div id=&quot;ChangeLog&quot;&gt;&amp;lt;pre&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt; <br>            &lt;/tr&gt; <br>        &lt;/tbody&gt; <br>    &lt;/table&gt; <br>    &lt;p&gt;&lt;a href=&quot;&quot;&gt;Go Back&lt;/a&gt;&lt;/p&gt; <br>    &lt;p&gt;&lt;a href=&quot;/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&quot;&gt;Modified Resource&lt;/a&gt;&lt;/p&gt; <br>    &lt;p&gt;&lt;a href=&quot;/tmp/sling/chunks&quot;&gt;Parent of Modified Resource&lt;/a&gt;&lt;/p&gt; <br>    &lt;/body&gt; <br>&lt;/html&gt; <br>{code} <br> <br> <br>h4. Last chunk upload <br>To indicate the last chunk, client additionally pass &quot;:lastChunk&quot; to true in request parameter. In last chunk upload response, the changelog has all the modification made in actual path repository. It would the same response as if client has uploaded file in single shot to [SlingPostServlet|http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html] <br>\[request\] <br></td></tr>
            <tr><td class="diff-unchanged" >{code:title= Last chunk upload request} <br></td></tr>
            <tr><td class="diff-changed-lines" >POST <span class="diff-changed-words">/content/dam<span class="diff-added-chars"style="background-color: #dfd;">/folder</span></span> HTTP/1.1 <br></td></tr>
            <tr><td class="diff-unchanged" >Authorization: Basic YWRtaW46YWRtaW4= <br>Transfer-Encoding: chunked <br></td></tr>
            <tr><td class="diff-changed-lines" >Content-Type: multipart/form-data; <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">boundary=XHnea0Y5RY92mJwpnKXHfl0dfhcqOCe</span> <span class="diff-added-words"style="background-color: #dfd;">boundary=lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt</span> <br></td></tr>
            <tr><td class="diff-unchanged" >Connection: Keep-Alive <br>User-Agent: Apache-HttpClient/4.1 (java 1.5) <br>Host: localhost:4502 <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">--XHnea0Y5RY92mJwpnKXHfl0dfhcqOCe</span> <span class="diff-added-words"style="background-color: #dfd;">--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt</span> <br>Content-Disposition: form-data; <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">name=&quot;:lastChunk&quot;</span> <span class="diff-added-words"style="background-color: #dfd;">name=&quot;catalog.pdf@Completed&quot;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >Content-Type: text/plain; charset=UTF-8 <br>Content-Transfer-Encoding: 8bit <br> <br>true <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">--XHnea0Y5RY92mJwpnKXHfl0dfhcqOCe</span> <span class="diff-added-words"style="background-color: #dfd;">--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt</span> <br>Content-Disposition: form-data; <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">name=&quot;:chunkNumber&quot;</span> <span class="diff-added-words"style="background-color: #dfd;">name=&quot;catalog.pdf@Offset&quot;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >Content-Type: text/plain; charset=UTF-8 <br>Content-Transfer-Encoding: 8bit <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">6</span> <span class="diff-added-words"style="background-color: #dfd;">400</span> <br><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">--XHnea0Y5RY92mJwpnKXHfl0dfhcqOCe</span> <span class="diff-added-words"style="background-color: #dfd;">--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt</span> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Content-Disposition: form-data; name=&quot;:chunkUploadId&quot; <br>Content-Type: text/plain; charset=UTF-8 <br>Content-Transfer-Encoding: 8bit <br> <br>/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08 <br>--XHnea0Y5RY92mJwpnKXHfl0dfhcqOCe <br></td></tr>
            <tr><td class="diff-changed-lines" >Content-Disposition: form-data; <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">name=&quot;*&quot;;</span> <span class="diff-added-words"style="background-color: #dfd;">name=&quot;catalog.pdf&quot;;</span> filename=&quot;catalog.pdf&quot; <br>Content-Type: <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">application/octet-stream</span> <span class="diff-added-words"style="background-color: #dfd;">application/pdf</span> <br></td></tr>
            <tr><td class="diff-unchanged" >Content-Transfer-Encoding: binary <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">$binary_data <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;"> </span> <span class="diff-added-words"style="background-color: #dfd;">--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt--</span> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">$binarydata <br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br>\[response\] <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The response shows that merge chunks uploaded at final destination and deletion of chunk upload metadata <br></td></tr>
            <tr><td class="diff-unchanged" >{code:title= Last chunk upload response} <br>HTTP/1.1 200 OK <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Server: Day-Servlet-Engine/4.1.42 <br>Content-Type: text/html;charset=UTF-8 <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Date: Thu, 28 Feb 2013 14:14:25 GMT <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Date: Mon, 06 May 2013 15:52:16 GMT <br></td></tr>
            <tr><td class="diff-unchanged" >Transfer-Encoding: chunked <br> <br>&lt;html&gt; <br>&lt;head&gt; <br></td></tr>
            <tr><td class="diff-changed-lines" >&lt;title&gt;Content modified <span class="diff-changed-words">/content/dam<span class="diff-added-chars"style="background-color: #dfd;">/folder</span>&lt;/title&gt;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >&lt;/head&gt; <br>    &lt;body&gt; <br></td></tr>
            <tr><td class="diff-changed-lines" >&lt;h1&gt;Content modified <span class="diff-changed-words">/content/dam<span class="diff-added-chars"style="background-color: #dfd;">/folder</span>&lt;/h1&gt;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >    &lt;table&gt; <br>        &lt;tbody&gt; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >            &lt;tr&gt; <br>                &lt;td&gt;Location&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">                &lt;td&gt;&lt;a href=&quot;/content/dam&quot; id=&quot;Location&quot;&gt;/content/dam&lt;/a&gt;&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">                &lt;td&gt;&lt;a href=&quot;/content/dam/folder&quot; id=&quot;Location&quot;&gt;/content/dam/folder&lt;/a&gt;&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-unchanged" >            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Parent Location&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">                &lt;td&gt;&lt;a href=&quot;/content&quot; id=&quot;ParentLocation&quot;&gt;/content&lt;/a&gt;&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">                &lt;td&gt;&lt;a href=&quot;/&quot; id=&quot;ParentLocation&quot;&gt;/&lt;/a&gt;&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-unchanged" >            &lt;/tr&gt; <br>            &lt;tr&gt; <br>                &lt;td&gt;Path&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-changed-lines" >&lt;td&gt;&lt;div <span class="diff-changed-words">id=&quot;Path&quot;&gt;/content/dam<span class="diff-added-chars"style="background-color: #dfd;">/folder</span>&lt;/div&gt;&lt;/td&gt;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >            &lt;/tr&gt; <br>            &lt;tr&gt; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >            &lt;tr&gt; <br>                &lt;td&gt;ChangeLog&lt;/td&gt; <br></td></tr>
            <tr><td class="diff-changed-lines" >&lt;td&gt;&lt;div <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">id=&quot;ChangeLog&quot;&gt;&amp;lt;pre&amp;gt;created(&quot;/content/dam/catalog.pdf&quot;);&amp;lt;br/&amp;gt;created(&quot;/content/dam/catalog.pdf/jcr:content&quot;);&amp;lt;br/&amp;gt;modified(&quot;/content/dam/catalog.pdf/jcr:content/jcr:lastModified&quot;);&amp;lt;br/&amp;gt;modified(&quot;/content/dam/catalog.pdf/jcr:content/jcr:mimeType&quot;);&amp;lt;br/&amp;gt;modified(&quot;/content/dam/catalog.pdf/jcr:content/jcr:data&quot;);&amp;lt;br/&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;</span> <span class="diff-added-words"style="background-color: #dfd;">id=&quot;ChangeLog&quot;&gt;&amp;lt;pre&amp;gt;modified(&quot;/content/dam/folder/catalog.pdf/jcr:content/jcr:lastModified&quot;);&amp;lt;br/&amp;gt;modified(&quot;/content/dam/folder/catalog.pdf/jcr:content/jcr:mimeType&quot;);&amp;lt;br/&amp;gt;modified(&quot;/content/dam/folder/catalog.pdf/jcr:content/jcr:data&quot;);&amp;lt;br/&amp;gt;deleted(&quot;/content/dam/folder/catalog.pdf/jcr:content/chunk_0_199&quot;);&amp;lt;br/&amp;gt;deleted(&quot;/content/dam/folder/catalog.pdf/jcr:content/chunk_200_399&quot;);&amp;lt;br/&amp;gt;deleted(&quot;/content/dam/folder/catalog.pdf/jcr:content/sling:chunksLength&quot;);&amp;lt;br/&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;</span> <br></td></tr>
            <tr><td class="diff-unchanged" >            &lt;/tr&gt; <br>        &lt;/tbody&gt; <br>    &lt;/table&gt; <br>    &lt;p&gt;&lt;a href=&quot;&quot;&gt;Go Back&lt;/a&gt;&lt;/p&gt; <br></td></tr>
            <tr><td class="diff-changed-lines" >&lt;p&gt;&lt;a <span class="diff-changed-words">href=&quot;/content/dam<span class="diff-added-chars"style="background-color: #dfd;">/folder</span>&quot;&gt;Modified</span> Resource&lt;/a&gt;&lt;/p&gt; <br>&lt;p&gt;&lt;a <span class="diff-changed-words">href=&quot;/<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">content</span>&quot;&gt;Parent</span> of Modified Resource&lt;/a&gt;&lt;/p&gt; <br></td></tr>
            <tr><td class="diff-unchanged" >    &lt;/body&gt; <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">&lt;/html<span class="diff-added-chars"style="background-color: #dfd;">&gt;</span></span> <br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The location header provides location of fully uploaded asset.The response contains the $md5_hash of merged binary.  <br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div>
<ul>
    <li><span class='TOCOutline'>1</span> <a href='#ChunkedFileUploadSupport-ChunkedFileUpload'>Chunked File Upload</a></li>
    <li><span class='TOCOutline'>2</span> <a href='#ChunkedFileUploadSupport-UseCases%3A'>Use Cases:</a></li>
    <li><span class='TOCOutline'>3</span> <a href='#ChunkedFileUploadSupport-Approach'>Approach</a></li>
    <li><span class='TOCOutline'>4</span> <a href='#ChunkedFileUploadSupport-ContentModel'>Content Model</a></li>
    <li><span class='TOCOutline'>5</span> <a href='#ChunkedFileUploadSupport-ProtocolSpecification'>Protocol Specification</a></li>
<ul>
    <li><span class='TOCOutline'>5.1</span> <a href='#ChunkedFileUploadSupport-UploadchunkusingPOST'>Upload chunk using POST</a></li>
    <li><span class='TOCOutline'>5.2</span> <a href='#ChunkedFileUploadSupport-QuerySlingabouttheinterruptedchunkuploadstatus'>Query Sling about the interrupted chunk upload status</a></li>
    <li><span class='TOCOutline'>5.3</span> <a href='#ChunkedFileUploadSupport-Abortchunkupload'>Abort chunk upload</a></li>
</ul>
    <li><span class='TOCOutline'>6</span> <a href='#ChunkedFileUploadSupport-Implementation'>Implementation</a></li>
<ul>
    <li><span class='TOCOutline'>6.1</span> <a href='#ChunkedFileUploadSupport-ExtensiontoSlingPostServlet'>Extension to SlingPostServlet</a></li>
    <li><span class='TOCOutline'>6.2</span> <a href='#ChunkedFileUploadSupport-ChunksStorage'>Chunks Storage</a></li>
    <li><span class='TOCOutline'>6.3</span> <a href='#ChunkedFileUploadSupport-Chunkprocessing'>Chunk processing</a></li>
</ul>
</ul></div>

<h1><a name="ChunkedFileUploadSupport-ChunkedFileUpload"></a>Chunked File Upload</h1>

<p>Status: DRAFT<br/>
Created: 20. January 2013<br/>
Author: shgupta<br/>
JIRA: <a href="https://issues.apache.org/jira/browse/SLING-2707" class="external-link" rel="nofollow">SLING-2707</a><br/>
References: - <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html" class="external-link" rel="nofollow">http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html</a><br/>
Updated: -</p>

<h1><a name="ChunkedFileUploadSupport-UseCases%3A"></a>Use Cases:</h1>
<p>1. Large file upload - With high speed internet connections, advent of cloud and HD going mainstream, Sling support large files (&gt; 2GB) upload.<br/>
2. Fault tolerant uploads - Sling provides capability to resume upload from failure point. It doesn't require client to restart the complete upload process. </p>

<h1><a name="ChunkedFileUploadSupport-Approach"></a>Approach</h1>
<p>Sling provides an extension to <a href="http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html" class="external-link" rel="nofollow">SlingPostServlet</a> which accepts file chunks in accordance with a specified protocol. Sling client slices the file in chunks, and upload the chunks in serial manner to server. Each chunk has "Offset" attribute which identify chunk position in complete file. <a href="http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html" class="external-link" rel="nofollow">SlingPostServlet</a>upon receiving the last chunk, stitches all chunks into a single file and save them to the final destination. </p>

<p>In case of upload failures, sling provides support to query the last chunk uploaded till failure point. Client resumes chunk upload from last failure point. </p>

<h1><a name="ChunkedFileUploadSupport-ContentModel"></a>Content Model</h1>
<p>Chunks are stored within actual path in sling:chunkMixin mixin node type. The content model to store chunk is defined as follows:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Content model to store chunk</b></div><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// node type to store chunk
</span><span class="code-comment">// offset: offset of chunk in file
</span><span class="code-comment">// jcr:data: binary of chunk
</span>[sling:chunkNode] &gt; nt:hierarchyNode
  primaryitem jcr:data
  - sling:offset  (<span class="code-object">long</span>) mandatory
  - jcr:data (binary) mandatory
 
 <span class="code-comment">//----------------------------------------------------------------------------- 
</span> <span class="code-comment">// Mixin node type to identify that a node has chunks
</span> <span class="code-comment">// sling:fileLength : length of complete file
</span> <span class="code-comment">// sling:chunksLength: cumulative length of all uploaded chunks
</span>[sling:chunkMixin]
  mixin
  - sling:fileLength (<span class="code-object">long</span>)
  - sling:chunksLength (<span class="code-object">long</span>)
  + * (sling:chunkNode) multiple
</pre>
</div></div>

<p>The typical nt:file node under chunked upload would look like </p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Typical nt:file nod under chunked upload</b></div><div class="codeContent panelContent">
<pre class="code-java">
/content/dam/folder/catalog.pdf [nt:file]
                                + jcr:content [nt:resource] [sling:chunkMixin]
                                    - jcr:data = empty until completed
                                    - sling:fileLength = 982145 <span class="code-comment">// (filename@Length from client)
</span>									- sling:chunksLength = 30000 <span class="code-comment">//cumulative length of all uploaded chunks
</span>                                    + chunk_0-9999 [sling:chunkNode]
                                            - sling:offset =0
                                            - jcr:data [binary data]
                                    + chunk_10000-19999 [sling:chunkNode]
                                    + ....
</pre>
</div></div>

<h1><a name="ChunkedFileUploadSupport-ProtocolSpecification"></a>Protocol Specification </h1>


<h3><a name="ChunkedFileUploadSupport-UploadchunkusingPOST"></a>Upload chunk using POST </h3>

<h4><a name="ChunkedFileUploadSupport-Chunkuploadrequest"></a>Chunk upload request</h4>
<p>Client uses POST method to parent path to upload binary chunk of file. Sling client passes $filename@Offset and $filename@Length as multipart request parameters. "Offset" indicate chunk's data offset in complete file. "Length" is optional parameter and indicates length of complete file. If "Length" parameter is known, Sling automatically calculates if request is last chunk request and according stitches all chunks and store it into final destination. <br/>
[request]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>First/Intermediate chunk upload request</b></div><div class="codeContent panelContent">
<pre class="code-java">
POST /content/dam/folder HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Transfer-Encoding: chunked
Content-Type: multipart/form-data; boundary=CbZDcL_DxJIVQqSG1WkYaIoLWqT3FGYCVe
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502

--CbZDcL_DxJIVQqSG1WkYaIoLWqT3FGYCVe
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf@Length"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

1000
--CbZDcL_DxJIVQqSG1WkYaIoLWqT3FGYCVe
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf@Offset"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

400
--CbZDcL_DxJIVQqSG1WkYaIoLWqT3FGYCVe
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf"</span>; filename=<span class="code-quote">"catalog.pdf"</span>
Content-Type: application/pdf
Content-Transfer-Encoding: binary
$binary-data
--CbZDcL_DxJIVQqSG1WkYaIoLWqT3FGYCVe--
</pre>
</div></div>

<p>[response]<br/>
The response shows that chunk is stored within the actual path in sling:chunkMixin node type</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Chunk upload response</b></div><div class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Day-Servlet-Engine/4.1.42
Content-Type: text/html;charset=UTF-8
Date: Mon, 06 May 2013 14:42:22 GMT
Transfer-Encoding: chunked

&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Content modified /content/dam/folder&lt;/title&gt;
&lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Content modified /content/dam/folder&lt;/h1&gt;
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;Status&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Status"</span>&gt;200&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Message&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Message"</span>&gt;OK&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Location&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"/content/dam/folder"</span> id=<span class="code-quote">"Location"</span>&gt;/content/dam/folder&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Parent Location&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"/"</span> id=<span class="code-quote">"ParentLocation"</span>&gt;/&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Path&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Path"</span>&gt;/content/dam/folder&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Referer&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"" id="</span>Referer"&gt;&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;ChangeLog&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"ChangeLog"</span>&gt;&amp;lt;pre&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/jcr:lastModified"</span>);&amp;lt;br/&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/jcr:mimeType"</span>);
&amp;lt;br/&amp;gt;created(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/chunk_400_799"</span>);&amp;lt;br/&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/chunk_400_799/jcr:data"</span>);&amp;lt;br/&amp;gt;
modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/chunk_400_799/sling:offset"</span>);&amp;lt;br/&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/sling:chunksLength"</span>);&amp;lt;br/&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;p&gt;&lt;a href=""&gt;Go Back&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href=<span class="code-quote">"/content/dam/folder"</span>&gt;Modified Resource&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href=<span class="code-quote">"/"</span>&gt;Parent of Modified Resource&lt;/a&gt;&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
</div></div>

<h4><a name="ChunkedFileUploadSupport-ChunkUploadinstreamingusecase"></a>Chunk Upload in streaming use case</h4>
<p>[request]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Last chunk upload request</b></div><div class="codeContent panelContent">
<pre class="code-java">
POST /content/dam/folder HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Transfer-Encoding: chunked
Content-Type: multipart/form-data; boundary=lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502

--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf@Completed"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

<span class="code-keyword">true</span>
--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf@Offset"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

400
--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf"</span>; filename=<span class="code-quote">"catalog.pdf"</span>
Content-Type: application/pdf
Content-Transfer-Encoding: binary
$binary_data

--lMaKIb2KPscWvPV8B0fULKkKayVtcxugD8Lt--
</pre>
</div></div>
<p>[response]<br/>
The response shows that merge chunks uploaded at final destination and deletion of chunk upload metadata</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Last chunk upload response</b></div><div class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Day-Servlet-Engine/4.1.42
Content-Type: text/html;charset=UTF-8
Date: Mon, 06 May 2013 15:52:16 GMT
Transfer-Encoding: chunked

&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Content modified /content/dam/folder&lt;/title&gt;
&lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Content modified /content/dam/folder&lt;/h1&gt;
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;Status&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Status"</span>&gt;200&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Message&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Message"</span>&gt;OK&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Location&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"/content/dam/folder"</span> id=<span class="code-quote">"Location"</span>&gt;/content/dam/folder&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Parent Location&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"/"</span> id=<span class="code-quote">"ParentLocation"</span>&gt;/&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Path&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Path"</span>&gt;/content/dam/folder&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Referer&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"" id="</span>Referer"&gt;&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;ChangeLog&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"ChangeLog"</span>&gt;&amp;lt;pre&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/jcr:lastModified"</span>);&amp;lt;br/&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/jcr:mimeType"</span>);&amp;lt;br/&amp;gt;modified(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/jcr:data"</span>);&amp;lt;br/&amp;gt;deleted(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/chunk_0_199"</span>);&amp;lt;br/&amp;gt;deleted(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/chunk_200_399"</span>);&amp;lt;br/&amp;gt;deleted(<span class="code-quote">"/content/dam/folder/catalog.pdf/jcr:content/sling:chunksLength"</span>);&amp;lt;br/&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;p&gt;&lt;a href=""&gt;Go Back&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href=<span class="code-quote">"/content/dam/folder"</span>&gt;Modified Resource&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href=<span class="code-quote">"/"</span>&gt;Parent of Modified Resource&lt;/a&gt;&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
</div></div>



<h3><a name="ChunkedFileUploadSupport-QuerySlingabouttheinterruptedchunkuploadstatus"></a>Query Sling about the interrupted chunk upload status</h3>
<p>Client sent get request on upload to retrieve chunk upload status.<br/>
[request]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Query interrupted chunk upload request</b></div><div class="codeContent panelContent">
<pre class="code-java">
GET /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08.json HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502
</pre>
</div></div>
<p>[response]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Query interrupted chunk upload response</b></div><div class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Day-Servlet-Engine/4.1.42
Content-Type: application/json;charset=UTF-8
Content-Length: 155
Date: Thu, 28 Feb 2013 14:14:25 GMT

{<span class="code-quote">"chunksUploaded"</span>:5,<span class="code-quote">"bytesUploaded"</span>:1600,<span class="code-quote">"jcr:createdBy"</span>:<span class="code-quote">"admin"</span>,<span class="code-quote">"jcr:created"</span>:<span class="code-quote">"Thu Feb 28 2013 19:44:24 GMT+0530"</span>,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"sling:OrderedFolder"</span>}
</pre>
</div></div>
<p>The above response means that 5 continuous chunks with size 1600 (index 0 to index 1599) are successfully uploaded to server. Client should start with :chunkNumber 6 and slice file from offset 1600.</p>

<h4><a name="ChunkedFileUploadSupport-Ifnobroken%2Fdiscontinueduploadslingreturns404notfoundresponse."></a>If no broken/discontinued upload sling returns 404 not found response. </h4>
<p>[response]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Chunk upload not found response</b></div><div class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 404 Not Found
Connection: Close
Server: Day-Servlet-Engine/4.1.42
Content-Type: text/html;charset=utf-8
Date: Thu, 28 Feb 2013 14:14:25 GMT
Transfer-Encoding: chunked

&lt;!DOCTYPE HTML PUBLIC <span class="code-quote">"-<span class="code-comment">//IETF//DTD HTML 2.0//EN"</span>&gt;
</span>&lt;html&gt;
    &lt;head&gt;&lt;title&gt;404 No resource found&lt;/title&gt;&lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;No resource found&lt;/h1&gt;
        &lt;p&gt;Cannot serve request to /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08 in /libs/sling/servlet/errorhandler/404.jsp&lt;/p&gt;
        
        &lt;h3&gt;Request Progress:&lt;/h3&gt;
&lt;pre&gt;
      0 (2013-02-28 19:44:25) TIMER_START{Request Processing}
      0 (2013-02-28 19:44:25) COMMENT timer_end format is {&amp;lt;elapsed msec&amp;gt;,&amp;lt;timer name&amp;gt;} &amp;lt;optional message&amp;gt;
      0 (2013-02-28 19:44:25) LOG Method=GET, PathInfo=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08
      0 (2013-02-28 19:44:25) TIMER_START{ResourceResolution}
      0 (2013-02-28 19:44:25) TIMER_END{0,ResourceResolution} URI=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08 resolves to Resource=, type=sling:nonexisting, path=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08, resource=[NonExistingResource, path=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08]
      0 (2013-02-28 19:44:25) LOG Resource Path Info: SlingRequestPathInfo: path='/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08', selectorString='<span class="code-keyword">null</span>', extension='<span class="code-keyword">null</span>', suffix='<span class="code-keyword">null</span>'
      0 (2013-02-28 19:44:25) TIMER_START{ServletResolution}
      0 (2013-02-28 19:44:25) TIMER_START{resolveServlet(, type=sling:nonexisting, path=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08, resource=[NonExistingResource, path=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08])}
      0 (2013-02-28 19:44:25) LOG {0}: no servlet found
      0 (2013-02-28 19:44:25) TIMER_END{0,resolveServlet(, type=sling:nonexisting, path=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08, resource=[NonExistingResource, path=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08])} Using servlet org.apache.sling.servlets.get.DefaultGetServlet
      0 (2013-02-28 19:44:25) TIMER_END{0,ServletResolution} URI=/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08 handled by Servlet=org.apache.sling.servlets.get.DefaultGetServlet
      0 (2013-02-28 19:44:25) LOG Applying Requestfilters
      0 (2013-02-28 19:44:25) LOG Calling filter: org.apache.sling.bgservlets.impl.BackgroundServletStarterFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: org.apache.sling.i18n.impl.I18NFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: org.apache.sling.rewriter.impl.RewriterFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.designimporter.CanvasPageDeleteRequestFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.core.impl.WCMRequestFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.adobe.granite.optout.impl.OptOutFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.theme.impl.ThemeResolverFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet
      0 (2013-02-28 19:44:25) LOG Calling filter: org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.mobile.core.impl.redirect.RedirectFilter
      0 (2013-02-28 19:44:25) LOG RedirectFilter did not redirect (request extension does not match)
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.core.impl.warp.TimeWarpFilter
      0 (2013-02-28 19:44:25) LOG Applying Componentfilters
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.core.impl.WCMComponentFilter
      0 (2013-02-28 19:44:25) LOG Calling filter: com.day.cq.wcm.core.impl.WCMDebugFilter
      0 (2013-02-28 19:44:25) TIMER_START{org.apache.sling.servlets.get.DefaultGetServlet#0}
      0 (2013-02-28 19:44:25) TIMER_END{0,org.apache.sling.servlets.get.DefaultGetServlet#0}
      0 (2013-02-28 19:44:25) LOG Applying Error filters
      0 (2013-02-28 19:44:25) LOG Calling filter: org.apache.sling.rewriter.impl.RewriterFilter
      0 (2013-02-28 19:44:25) TIMER_START{handleError:status=404}
      0 (2013-02-28 19:44:25) TIMER_END{0,handleError:status=404} Using handler /libs/sling/servlet/errorhandler/404.jsp
      0 (2013-02-28 19:44:25) LOG Found processor <span class="code-keyword">for</span> post processing ProcessorConfiguration: {contentTypes=[text/html],order=-1, active=<span class="code-keyword">true</span>, valid=<span class="code-keyword">true</span>, processErrorResponse=<span class="code-keyword">true</span>, pipeline=(generator=Config(type=htmlparser, config={}), transformers=(Config(type=linkchecker, config={}), Config(type=mobile, config=org.apache.sling.jcr.resource.JcrPropertyMap@42e95cbf), Config(type=mobiledebug, config=org.apache.sling.jcr.resource.JcrPropertyMap@66c821ea), Config(type=contentsync, config=org.apache.sling.jcr.resource.JcrPropertyMap@5d2abe5d), serializer=Config(type=htmlwriter, config={}))}
      0 (2013-02-28 19:44:25) TIMER_END{0,Request Processing} Dumping SlingRequestProgressTracker Entries
&lt;/pre&gt;

        
        &lt;hr&gt;
        &lt;address&gt;ApacheSling/2.2 (Day-Servlet-Engine/4.1.42, Java HotSpot(TM) 64-Bit Server VM 1.6.0_26, Windows 7 6.1 amd64)&lt;/address&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
</div></div>

<h3><a name="ChunkedFileUploadSupport-Abortchunkupload"></a>Abort chunk upload</h3>
<p>Client will send delete" operation on upload id to  <a href="http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html" class="external-link" rel="nofollow">SlingPostServlet</a> to abort chunk upload.<br/>
[request]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Abort chunk upload request</b></div><div class="codeContent panelContent">
<pre class="code-java">
POST /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08 HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Length: 207
Content-Type: multipart/form-data; boundary=tBnruF3YNdCs-besNxXn8zWO6bN1GL_
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502

--tBnruF3YNdCs-besNxXn8zWO6bN1GL_
Content-Disposition: form-data; name=<span class="code-quote">":operation"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

delete
--tBnruF3YNdCs-besNxXn8zWO6bN1GL_--

</pre>
</div></div>
<p>[response]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Abort chunk upload response</b></div><div class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Day-Servlet-Engine/4.1.42
Content-Type: text/html;charset=UTF-8
Date: Thu, 28 Feb 2013 14:14:25 GMT
Transfer-Encoding: chunked

&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Content modified /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&lt;/title&gt;
&lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Content modified /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&lt;/h1&gt;
    &lt;table&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;Status&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Status"</span>&gt;200&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Message&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Message"</span>&gt;OK&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Location&lt;/td&gt;
                &lt;td&gt;&lt;img src=<span class="code-quote">"/libs/cq/linkchecker/resources/linkcheck_o.gif"</span> alt=<span class="code-quote">"invalid link: /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08"</span> title=<span class="code-quote">"invalid link: /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08"</span> border=<span class="code-quote">"0"</span>&gt;/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&lt;img src=<span class="code-quote">"/libs/cq/linkchecker/resources/linkcheck_c.gif"</span> border=<span class="code-quote">"0"</span>&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Parent Location&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"/tmp/sling/chunks"</span> id=<span class="code-quote">"ParentLocation"</span>&gt;/tmp/sling/chunks&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Path&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"Path"</span>&gt;/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Referer&lt;/td&gt;
                &lt;td&gt;&lt;a href=<span class="code-quote">"" id="</span>Referer"&gt;&lt;/a&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;ChangeLog&lt;/td&gt;
                &lt;td&gt;&lt;div id=<span class="code-quote">"ChangeLog"</span>&gt;&amp;lt;pre&amp;gt;deleted(<span class="code-quote">"/tmp/sling/chunks/21d36856b76045da8719ac932f88fe08"</span>);&amp;lt;br/&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;p&gt;&lt;a href=""&gt;Go Back&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&lt;img src=<span class="code-quote">"/libs/cq/linkchecker/resources/linkcheck_o.gif"</span> alt=<span class="code-quote">"invalid link: /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08"</span> title=<span class="code-quote">"invalid link: /tmp/sling/chunks/21d36856b76045da8719ac932f88fe08"</span> border=<span class="code-quote">"0"</span>&gt;Modified Resource&lt;img src=<span class="code-quote">"/libs/cq/linkchecker/resources/linkcheck_c.gif"</span> border=<span class="code-quote">"0"</span>&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href=<span class="code-quote">"/tmp/sling/chunks"</span>&gt;Parent of Modified Resource&lt;/a&gt;&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
</div></div>

<h1><a name="ChunkedFileUploadSupport-Implementation"></a>Implementation</h1>

<h3><a name="ChunkedFileUploadSupport-ExtensiontoSlingPostServlet"></a>Extension to <a href="http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html" class="external-link" rel="nofollow">SlingPostServlet</a></h3>
<p>Chunk upload is supported in "modify"operation of <a href="http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html" class="external-link" rel="nofollow">SlingPostServlet</a> ( ie. In default operation) . No new operation introduced for it</p>
<h3><a name="ChunkedFileUploadSupport-ChunksStorage"></a>Chunks Storage</h3>
<p>Chunks are saved in temporary location identified by upload id in the following node structure. <br/>
[request]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Get chunks information</b></div><div class="codeContent panelContent">
<pre class="code-java">
GET /tmp/sling/chunks/f4bc84fbee4d4a608a87c1bf347ddded.infinity.json HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502
</pre>
</div></div>

<p>[response]</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Get chunks information response</b></div><div class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Day-Servlet-Engine/4.1.42
Content-Type: application/json;charset=UTF-8
Content-Length: 155
Date: Thu, 28 Feb 2013 15:09:53 GMT
{<span class="code-quote">"chunksUploaded"</span>:5,<span class="code-quote">"jcr:createdBy"</span>:<span class="code-quote">"admin"</span>,<span class="code-quote">"bytesUploaded"</span>:1600,<span class="code-quote">"jcr:created"</span>:<span class="code-quote">"Thu Feb 28 2013 20:39:53 GMT+0530"</span>,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"sling:OrderedFolder"</span>,<span class="code-quote">"1"</span>:{<span class="code-quote">"size"</span>:200,<span class="code-quote">":jcr:data"</span>:200,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"nt:unstructured"</span>},<span class="code-quote">"2"</span>:{<span class="code-quote">"size"</span>:300,<span class="code-quote">":jcr:data"</span>:300,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"nt:unstructured"</span>},<span class="code-quote">"3"</span>:{<span class="code-quote">"size"</span>:300,<span class="code-quote">":jcr:data"</span>:300,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"nt:unstructured"</span>},<span class="code-quote">"4"</span>:{<span class="code-quote">"size"</span>:400,<span class="code-quote">":jcr:data"</span>:400,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"nt:unstructured"</span>},<span class="code-quote">"5"</span>:{<span class="code-quote">"size"</span>:400,<span class="code-quote">":jcr:data"</span>:400,<span class="code-quote">"jcr:primaryType"</span>:<span class="code-quote">"nt:unstructured"</span>}}
</pre>
</div></div>
<h3><a name="ChunkedFileUploadSupport-Chunkprocessing"></a>Chunk processing</h3>
<ul>
	<li>First/Intermediate chunks: Chunk is saved in temporary location in jcr. Ignores all upload semantics (@TypeHint, etc) and request parameters.</li>
	<li>Last chunk: Stitches all chunks. Process all upload semantics and request parameters and creates jcr node structure at the right location.</li>
</ul>



    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=30749779&revisedVersion=38&originalVersion=37">View Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message