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 Tue, 07 May 2013 03:07: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 (6)</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" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >h1. Error <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">Conditions</span>
<span class="diff-added-words"style="background-color: #dfd;">Scenarios</span>
<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h4. Start resumable upload
from non zero offset <br></td></tr>
            <tr><td class="diff-changed-lines" >Sling sends 500 internal server
error along with error message <span class="diff-added-words"style="background-color: #dfd;">&quot;no
chunk upload found at {path}</span> wrapped javax.jcr.RepositoryException. <br></td></tr>
            <tr><td class="diff-unchanged" >{code:title= Start chunk upload request
from non-zero offset} <br>POST /content/dam/folder HTTP/1.1 <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >\[response\] <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{code:title=
500 internal server error } <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{code:title=
No chunk upload found } <br></td></tr>
            <tr><td class="diff-unchanged" >HTTP/1.1 500 Internal Server Error
<br>Connection: Close <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h4. Upload noncontinuous upload <br>
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Sling
sends 500 internal server error along with error message &quot;Chunk&#39;s offset
{actual offset } doesn&#39;t match expected offset {expected offset} wrapped javax.jcr.RepositoryException.
 <br>{code:title= Noncontinuous chunk upload request} <br>POST /content/dam/folder
HTTP/1.1 <br>Authorization: Basic YWRtaW46YWRtaW4= <br>Transfer-Encoding: chunked
<br>Content-Type: multipart/form-data; boundary=i3nkScb8nmEmcC87H-LOXKXPO5cutm6 <br>Connection:
Keep-Alive <br>User-Agent: Apache-HttpClient/4.1 (java 1.5) <br>Host: localhost:4502
<br> <br>--i3nkScb8nmEmcC87H-LOXKXPO5cutm6 <br>Content-Disposition: form-data;
name=&quot;catalog.pdf@Length&quot; <br>Content-Type: text/plain; charset=UTF-8
<br>Content-Transfer-Encoding: 8bit <br> <br>1000 <br>--i3nkScb8nmEmcC87H-LOXKXPO5cutm6
<br>Content-Disposition: form-data; name=&quot;catalog.pdf@Offset&quot; <br>Content-Type:
text/plain; charset=UTF-8 <br>Content-Transfer-Encoding: 8bit <br> <br>200
<br>--i3nkScb8nmEmcC87H-LOXKXPO5cutm6 <br>Content-Disposition: form-data; name=&quot;catalog.pdf&quot;;
filename=&quot;catalog.pdf&quot; <br>Content-Type: application/pdf <br>Content-Transfer-Encoding:
binary <br> <br>$binary_data <br>--i3nkScb8nmEmcC87H-LOXKXPO5cutm6-- <br>{code}
<br> <br>\[response\] <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{code:title=
Offset mismatch error } <br>HTTP/1.1 500 Internal Server Error <br>Connection:
Close <br>Server: Day-Servlet-Engine/4.1.42 <br>Content-Type: text/html;charset=UTF-8
<br>Date: Mon, 06 May 2013 16:09:58 GMT <br>Transfer-Encoding: chunked <br>
<br>&lt;html&gt; <br>&lt;head&gt; <br>    &lt;title&gt;Error
while processing /content/dam/folder&lt;/title&gt; <br>&lt;/head&gt;
<br>    &lt;body&gt; <br>    &lt;h1&gt;Error while processing
/content/dam/folder&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;500&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;javax.jcr.RepositoryException: Chunk&#39;s offset
{200} doesn&#39;t match expected offset {600}&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;/content/dam/folder&quot; id=&quot;Location&quot;&gt;/content/dam/folder&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;/&quot; id=&quot;ParentLocation&quot;&gt;/&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;/content/dam/folder&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;/content/dam/folder&quot;&gt;Modified
Resource&lt;/a&gt;&lt;/p&gt; <br>    &lt;p&gt;&lt;a href=&quot;/&quot;&gt;Parent
of Modified Resource&lt;/a&gt;&lt;/p&gt; <br>    &lt;/body&gt;
<br>&lt;/html&gt; <br>{code} <br> <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-ErrorScenarios'>Error
Scenarios</a></li>
</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 <span class="code-comment">//content/dam/folder/catalog.pdf.3.json HTTP/1.1
</span>Authorization: Basic YWRtaW46YWRtaW4=
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502
</pre>
</div></div>
<p>[response]<br/>
sling:chunksLength property indicate cumulative length of all chunks stored in sling. Sling
client should resume upload from sling:chunksLength property's value offset</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">
{<span class="code-quote">"jcr:createdBy"</span>:<span class="code-quote">"admin"</span>,<span
class="code-quote">"jcr:created"</span>:<span class="code-quote">"Mon May 06
2013 21:31:22 GMT+0530"</span>,<span class="code-quote">"jcr:primaryType"</span>:<span
class="code-quote">"nt:file"</span>,<span class="code-quote">"jcr:content"</span>:{<span
class="code-quote">"jcr:lastModifiedBy"</span>:<span class="code-quote">"admin"</span>,
<span class="code-quote">"jcr:uuid"</span>:<span class="code-quote">"845e9cee-f963-4f72-b115-fa021859c809"</span>,<span
class="code-quote">":jcr:data"</span>:0,<span class="code-quote">"jcr:mixinTypes"</span>:[<span
class="code-quote">"sling:chunkMixin"</span>],<span class="code-quote">"sling:chunksLength"</span>:200,<span
class="code-quote">"jcr:mimeType"</span>:<span class="code-quote">"application/pdf"</span>,
<span class="code-quote">"jcr:lastModified"</span>:<span class="code-quote">"Mon
May 06 2013 21:31:22 GMT+0530"</span>, <span class="code-quote">"jcr:primaryType"</span>:<span
class="code-quote">"nt:resource"</span>,<span class="code-quote">"sling:fileLength"</span>:1700,<span
class="code-quote">"chunk_0_199"</span>:{<span class="code-quote">"jcr:createdBy"</span>:<span
class="code-quote">"admin"</span>,<span class="code-quote">":jcr:data"</span>:200,<span
class="code-quote">"sling:offset"</span>:0,<span class="code-quote">"jcr:created"</span>:<span
class="code-quote">"Mon May 06 2013 21:31:22 GMT+0530"</span>,<span class="code-quote">"jcr:primaryType"</span>:<span
class="code-quote">"sling:chunkNode"</span>}}
</pre>
</div></div>

<h3><a name="ChunkedFileUploadSupport-Abortchunkupload"></a>Abort chunk
upload</h3>
<p>To abort chunk upload Sling client passes ":operation=delete" request parameter along
with ":applyToChunks=true".</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Abort incomplete chunk upload request</b></div><div
class="codeContent panelContent">
<pre class="code-java">
POST /content/dam/folder/catalog.pdf HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Length: 403
Content-Type: multipart/form-data; boundary=dDzF5u2n-HJu5tudkdVpFucFsmqcVV-CONtRqlL
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502

--dDzF5u2n-HJu5tudkdVpFucFsmqcVV-CONtRqlL
Content-Disposition: form-data; name=<span class="code-quote">":applyToChunks"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

<span class="code-keyword">true</span>
--dDzF5u2n-HJu5tudkdVpFucFsmqcVV-CONtRqlL
Content-Disposition: form-data; name=<span class="code-quote">":operation"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

delete
--dDzF5u2n-HJu5tudkdVpFucFsmqcVV-CONtRqlL--
</pre>
</div></div>

<p>[response]<br/>
Sling removes nt:file node for a new resumable upload and individual chunks on a existing
nt:file node. </p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Abort incomplete 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 16:09:58 GMT
Transfer-Encoding: chunked

&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Content modified /content/dam/folder/catalog.pdf&lt;/title&gt;
&lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Content modified /content/dam/folder/catalog.pdf&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/catalog.pdf"</span>
id=<span class="code-quote">"Location"</span>&gt;/content/dam/folder/catalog.pdf&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">"/content/dam/folder"</span>
id=<span class="code-quote">"ParentLocation"</span>&gt;/content/dam/folder&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/catalog.pdf&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">"/content/dam/folder/catalog.pdf"</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/catalog.pdf"</span>&gt;Modified
Resource&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href=<span class="code-quote">"/content/dam/folder"</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-ErrorScenarios"></a>Error Scenarios</h1>

<h4><a name="ChunkedFileUploadSupport-Startresumableuploadfromnonzerooffset"></a>Start
resumable upload from non zero offset</h4>
<p>Sling sends 500 internal server error along with error message "no chunk upload found
at </p>
<div class="error"><span class="error">Unknown macro: {path}</span> </div>
<p> wrapped javax.jcr.RepositoryException. </p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Start chunk upload request from non-zero offset</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=4SC3O7Wgs4nrN8yqNaH1TNfQRxPK62
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502

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

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

200
--4SC3O7Wgs4nrN8yqNaH1TNfQRxPK62
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
--4SC3O7Wgs4nrN8yqNaH1TNfQRxPK62--
</pre>
</div></div>

<p>[response]</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>No chunk upload found</b></div><div
class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 500 Internal Server Error
Connection: Close
Server: Day-Servlet-Engine/4.1.42
Content-Type: text/html;charset=UTF-8
Date: Mon, 06 May 2013 16:22:55 GMT
Transfer-Encoding: chunked

&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Error <span class="code-keyword">while</span> processing
/content/dam/folder&lt;/title&gt;
&lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Error <span class="code-keyword">while</span> processing
/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;500&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;javax.jcr.RepositoryException:
no chunk upload found at {/content/dam/folder/catalog.pdf}&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;&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-Uploadnoncontinuousupload"></a>Upload
noncontinuous upload</h4>

<p>Sling sends 500 internal server error along with error message "Chunk's offset </p>
<div class="error"><span class="error">Unknown macro: {actual offset }</span>
</div>
<p> doesn't match expected offset </p>
<div class="error"><span class="error">Unknown macro: {expected offset}</span>
</div>
<p> wrapped javax.jcr.RepositoryException. </p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Noncontinuous 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=i3nkScb8nmEmcC87H-LOXKXPO5cutm6
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: localhost:4502

--i3nkScb8nmEmcC87H-LOXKXPO5cutm6
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
--i3nkScb8nmEmcC87H-LOXKXPO5cutm6
Content-Disposition: form-data; name=<span class="code-quote">"catalog.pdf@Offset"</span>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

200
--i3nkScb8nmEmcC87H-LOXKXPO5cutm6
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
--i3nkScb8nmEmcC87H-LOXKXPO5cutm6--
</pre>
</div></div>

<p>[response]</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Offset mismatch error</b></div><div
class="codeContent panelContent">
<pre class="code-java">
HTTP/1.1 500 Internal Server Error
Connection: Close
Server: Day-Servlet-Engine/4.1.42
Content-Type: text/html;charset=UTF-8
Date: Mon, 06 May 2013 16:09:58 GMT
Transfer-Encoding: chunked

&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Error <span class="code-keyword">while</span> processing
/content/dam/folder&lt;/title&gt;
&lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Error <span class="code-keyword">while</span> processing
/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;500&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;javax.jcr.RepositoryException:
Chunk's offset {200} doesn't match expected offset {600}&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;&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>

    </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=46&originalVersion=45">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