Ejemplo n.º 1
0
 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);
 }