Index: wp-includes/class-wp-xmlrpc-server.php
===================================================================
--- wp-includes/class-wp-xmlrpc-server.php	(revision 21425)
+++ wp-includes/class-wp-xmlrpc-server.php	(working copy)
@@ -4524,13 +4524,27 @@
 		$data        = $args[3];
 
 		$name = sanitize_file_name( $data['name'] );
+
+		$path = '';
+		if( ! empty( $data['path'] ) )
+			$path = $data['path'];
+
+		$url = '';
+		if( ! empty( $data['url'] ) )
+			$url = $data['url'];
+
+		$filesize = 0;
+		if( ! empty( $data['filesize'] ) )
+			$filesize = $data['filesize'];
+
 		$type = $data['type'];
-		$bits = $data['bits'];
+		$bits = base64_decode( $data['bits'] );
 
 		if ( !$user = $this->login($username, $password) )
 			return $this->error;
 
-		do_action('xmlrpc_call', 'metaWeblog.newMediaObject');
+		if ( empty( $data['resume'] ) || false == $data['resume'] )
+			do_action('xmlrpc_call', 'metaWeblog.newMediaObject');
 
 		if ( !current_user_can('upload_files') ) {
 			$this->error = new IXR_Error( 401, __( 'You do not have permission to upload files.' ) );
@@ -4558,36 +4572,80 @@
 			$name = "wpid{$old_file->ID}-{$filename}";
 		}
 
-		$upload = wp_upload_bits($name, null, $bits);
-		if ( ! empty($upload['error']) ) {
-			$errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']);
-			return new IXR_Error(500, $errorString);
+		if ( ! empty( $data['resume'] ) && true == $data['resume'] && $data['location'] > 0 ) {
+  			if( ! file_exists( $path ) )
+				return new IXR_Error( 500, sprintf( __( 'File %1$s does not exist' ), $name ) );
+
+			// Continue uploading the file
+			if( ! file_exists( $path ) )
+				return new IXR_Error( 500, sprintf( __( 'File %1$s does not exist' ), $name ) );
+			
+			if( filesize( $path ) != $data['location'] )
+				return new IXR_Error( 500, sprintf( __( '%1$d is an invalid write position for file %2$s' ), $data['location'], $name ) );
+				
+			$fh = fopen( $path, 'a' );
+			if( ! $fh )
+				return new IXR_Error( 500, sprintf( __( 'Unable to open file %1$s for writing' ), $name ) );
+				
+			$res = fwrite( $fh, $bits );
+			if( false === $res )
+				return new IXR_Error( 500, sprintf( __( 'Unable to write to file %1$s' ), $name ) );
+
+			clearstatcache();
+			fclose( $fh );
 		}
-		// Construct the attachment array
-		// attach to post_id 0
-		$post_id = 0;
-		$attachment = array(
-			'post_title' => $name,
-			'post_content' => '',
-			'post_type' => 'attachment',
-			'post_parent' => $post_id,
-			'post_mime_type' => $type,
-			'guid' => $upload[ 'url' ]
-		);
+		else {
+			// Create a new file (resumable or non)
+			$upload = wp_upload_bits($name, null, $bits);
+			if ( ! empty($upload['error']) ) {
+				$errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']);
+				return new IXR_Error(500, $errorString);
+			}
+		
+			$path = $upload['file'];
+			$url = $upload['url'];
+		}
 
-		// Save the data
-		$id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );
-		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
+		if( empty( $data['resume'] ) || false == $data['resume'] ||
+			( ! empty( $data['resume'] ) && true == $data['resume'] && filesize( $path ) >= $filesize ) ) {
+			// Either this is a non-resumable upload, or we've finished uploading a resumable upload
 
-		do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args );
+			// Construct the attachment array
+			// attach to post_id 0
+			$post_id = 0;
+			$attachment = array(
+				'post_title' => $name,
+				'post_content' => '',
+				'post_type' => 'attachment',
+				'post_parent' => $post_id,
+				'post_mime_type' => $type,
+				'guid' => $url
+			);
+	
+			// Save the data
+			$id = wp_insert_attachment( $attachment, $path, $post_id );
+			wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $path ) );
+	
+			do_action( 'xmlrpc_call_success_mw_newMediaObject', $id, $args );
+	
+			$struct = array(
+				'id'   => strval( $id ),
+				'file' => $name,
+				'url'  => $url,
+				'type' => $type
+			);
+			return apply_filters( 'wp_handle_upload', $struct, 'upload' );
+		}
+		else {
+			$struct = array(
+				'file' => $name,
+				'url'  => $url,
+				'type' => $type,
+				'path' => $path,
+			);
 
-		$struct = array(
-			'id'   => strval( $id ),
-			'file' => $name,
-			'url'  => $upload[ 'url' ],
-			'type' => $type
-		);
-		return apply_filters( 'wp_handle_upload', $struct, 'upload' );
+			return apply_filters( 'wp_handle_resumable_upload', $struct, 'upload' );
+		}
 	}
 
 	/* MovableType API functions
