Skip to content
Davit Barbakadze edited this page Jun 23, 2013 · 13 revisions

Table of Contents

### Some insight

Plupload has a built-in support for chunking, although it is disabled by default. What happens when it is activated, is that instead of sending a complete file, Plupload splits it into chunks of predefined size and uploads them one by one to be reassembled back to a complete file on a server-side. Obviously such procedure requires some additional care from upload handler (see below).

Check: "When to use chunking and when not?" from our FAQ for a bit of history and theory behind the chunking feature in Plupload.

### Configuration

We will build up on a code from Getting Started, all we need to add though is only a chunk_size option:

var uploader = new plupload.Uploader({
	browse_button: 'browse', // this can be an id of a DOM element or the DOM element itself
	url: 'upload.php',
	chunks_size: '200kb',
	max_retries: 3
});

chunk_size accepts either an amount in bytes or a formatted string, e.g: 204800 or "204800b"`` or "200kb".

### Events

Each uploaded chunk triggers ChunkUploaded event if upload was successful and Error (plupload.HTTP_ERROR) if upload failed for some reason. Additionally if max_retries option is set and is bigger than 0, which is default, chunk will be re-uploaded that many times in case of failure, before it actually results in Error event.

ChunkUploaded is similar to FileUploaded event. The only real difference is that the former relates to a part of the file and contains some additional properties in a third argument:

uploader.bind('ChunkUploaded', function(up, file, info) {
     // do some chunk related stuff
});

info contains the following properties:

  • offset - chunk offset in bytes from the beginning of the file
  • total - full file size
  • status - HTTP status code (e.g. 200)
  • response - full server response in the text form
  • responseHeaders - HTTP response headers (in some cases might be empty, for example in html4 runtime)
### Server-side handling

Along with each chunk three additional arguments are sent - the name of the file, total number of chunks and the ordinal number of the current chunk in a whole sequence. This is how you can handle it in PHP for example:

<?php

if (empty($_FILES) || $_FILES['file']['error']) {
	die('{"OK": 0, "info": "Failed to move uploaded file."}');
}

$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;

$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : $_FILES["file"]["name"];
$filePath = "uploads/$fileName";


// Open temp file
$out = @fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
if ($out) {
	// Read binary input stream and append it to temp file
	$in = @fopen($_FILES['file']['tmp_name'], "rb");

	if ($in) {
		while ($buff = fread($in, 4096))
			fwrite($out, $buff);
	} else
		die('{"OK": 0, "info": "Failed to open input stream."}');

	@fclose($in);
	@fclose($out);

	@unlink($_FILES['file']['tmp_name']);
} else
	die('{"OK": 0, "info": "Failed to open output stream."}');


// Check if file has been uploaded
if (!$chunks || $chunk == $chunks - 1) {
	// Strip the temp .part suffix off 
	rename("{$filePath}.part", $filePath);
}

die('{"OK": 1, "info": "Upload successful."}');

Notice that this code is written so that it can successfully handle upload with or without chunking.