public function method_PUT($stream) { // Assert the privileges of the current user if (DAV::getPath() === $this->path) { $this->assert(DAVACL::PRIV_WRITE_CONTENT); } // Try to open the (local) file for writing if (!($resource = fopen($this->localPath, 'w'))) { throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR); } // Try to write to the file. try { $size = 0; // Do we know how big this file will be? if (($cl = (int) @$_SERVER['CONTENT_LENGTH']) || ($cl = (int) @$_SERVER['HTTP_X_EXPECTED_ENTITY_LENGTH'])) { # The client has indicated the length of the request entity body: set_time_limit(120); $time = time(); // Loop until we reach the end of the request body (or when we have read the indicated length) while ($cl && !feof($stream)) { // Make sure the script doesn't timeout if (time() - $time > 60) { set_time_limit(120); $time = time(); } // Determine the size of the chunk we will read $chunk_size = $cl; if ($chunk_size > DAV::$CHUNK_SIZE) { $chunk_size = DAV::$CHUNK_SIZE; } // Read a chunk from the request body and write it to the (local) file $buffer = fread($stream, $chunk_size); $chunk_size = strlen($buffer); if ($chunk_size !== fwrite($resource, $buffer)) { throw new DAV_Status(DAV::HTTP_INSUFFICIENT_STORAGE); } $size += $chunk_size; // $cl contains the number of bytes to read: the HTTP 'Content-Length' // header minus the number of bytes we have already read $cl -= $chunk_size; } // If $cl is still bigger than 0, that means we've met the end of the body // before reading the number of bytes indicated by the HTTP header if ($cl) { throw new DAV_Status(DAV::HTTP_BAD_REQUEST, 'Request entity too small'); } } else { # The client didn't give us any clue about the request body entity size. # Let's make the best of it... set_time_limit(120); $time = time(); // We break out of this loop, from within it while (true) { // Make sure the script doesn't timeout if (time() - $time > 60) { set_time_limit(120); $time = time(); } // Read a chunk from the request body ... $buffer = fread($stream, DAV::$CHUNK_SIZE); if ($buffer === false || $buffer === '') { // If the buffer is empty, we apparantly reached the end of the file break; } // ... and write it to the (local) file $bufferSize = strlen($buffer); if ($bufferSize !== fwrite($resource, $buffer)) { throw new DAV_Status(DAV::HTTP_INSUFFICIENT_STORAGE); } $size += $bufferSize; } } } catch (DAV_Status $e) { // If at some point this fails, we will close the file properly before // rethrowing the (DAV_Status) exception. fclose($resource); unlink($this->localPath); throw $e; } // The file is successfully saved, close it and store some metadata fclose($resource); $contenttype = $this->user_prop_getcontenttype(); if (!$contenttype) { // If we can't determine or set the content type, just ignore this problem try { $this->set_getcontenttype(BeeHub::determineContentType($this->path)); } catch (DAV_Status $e) { } } $this->user_set(DAV::PROP_GETCONTENTLENGTH, $size); $this->user_set(DAV::PROP_GETETAG, BeeHub::ETag()); $this->storeProperties(); // Reread the file system data $this->stat = stat($this->localPath); }