private function internal_create_member($name, $collection = false) { $this->assert(DAVACL::PRIV_WRITE_CONTENT); $path = $this->path . $name; $localPath = BeeHub::localPath($path); $cups = $this->current_user_principals(); // Determine the sponsor $user = BeeHub::getAuth()->current_user(); if (!is_null($user)) { $user_sponsors = $user->user_prop_sponsor_membership(); } if (is_null($user) || count($user_sponsors) == 0) { // If the user doesn't have any sponsors, he/she can't create files and directories throw DAV::forbidden("You need to be logged in and have at least one sponsor to upload files"); } $sponsor = $this->user_prop(BeeHub::PROP_SPONSOR); // The default is the directory sponsor if (!in_array($sponsor, $user_sponsors)) { //But a user can only create files sponsored by his own sponsors $sponsor = $user->user_prop(BeeHub::PROP_SPONSOR); } // Create the subdirectory or file if (file_exists($localPath)) { throw DAV::forbidden(); } $result = $collection ? @mkdir($localPath) : touch($localPath); if (!$result) { throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR); } // And create the object in the database $unslashifiedPath = \DAV::unslashify($path); if (substr($unslashifiedPath, 0, 1) === '/') { $unslashifiedPath = substr($unslashifiedPath, 1); } $document = array('path' => $unslashifiedPath, 'depth' => substr_count($unslashifiedPath, '/') + 1); if ($collection) { $document['collection'] = true; } $filesCollection = BeeHub::getNoSQL()->files; $filesCollection->save($document); // And set the attributes $new_resource = DAV::$REGISTRY->resource($path); if (!$collection) { $new_resource->user_set(DAV::PROP_GETETAG, BeeHub::ETag()); } $new_resource->user_set(DAV::PROP_OWNER, $this->user_prop_current_user_principal()); $new_resource->user_set(BeeHub::PROP_SPONSOR, $sponsor); $new_resource->storeProperties(); return $new_resource; }
public function method_PUT_range($stream, $start, $end, $total) { // Assert the privileges of the current user $this->assert(DAVACL::PRIV_WRITE_CONTENT); // Open file for reading and writing if (!($resource = fopen($this->localPath, 'r+'))) { throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR); } // Try to write to the file. try { // Go to the point in the file where we want to write if (0 !== fseek($resource, $start, SEEK_SET)) { throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR); } // Check the HTTP headers; length and range should match $sizeLeft = $end - $start + 1; $newSize = $start; // The start byte indicates the number of bytes before this ranged PUT if (!array_key_exists('CONTENT_LENGTH', $_SERVER)) { throw new DAV_Status(DAV::HTTP_LENGTH_REQUIRED); } if ((int) $_SERVER['CONTENT_LENGTH'] !== $sizeLeft) { throw new DAV_Status(DAV::HTTP_BAD_REQUEST, 'Content-Range and Content-Length are incompatible.'); } // Read the request body and write it to the file while ($sizeLeft && !feof($stream)) { // We keep resetting the time limit to 10 minutes so the script won't get killed during long uploads. This means your minimum connection speed should be DAV::$CHUNK_SIZE / 600 bytes per second set_time_limit(120); $buffer = fread($stream, DAV::$CHUNK_SIZE); $bufferSize = strlen($buffer); $sizeLeft -= $bufferSize; if (strlen($buffer) !== fwrite($resource, $buffer)) { throw new DAV_Status(DAV::HTTP_INSUFFICIENT_STORAGE); } $newSize += $bufferSize; } // If not the complete indicated sized could be read from the request body, then the request was wrong! if ($sizeLeft) { throw new DAV_Status(DAV::HTTP_BAD_REQUEST, 'Request entity too small'); } } catch (DAV_Status $e) { // If at some point this fails, we will close the file properly before // rethrowing the (DAV_Status) exception. fclose($resource); throw $e; } // The file is successfully saved, close it and store some metadata fclose($resource); $this->user_set(DAV::PROP_GETETAG, BeeHub::ETag()); if ($newSize > $this->user_prop_getcontentlength()) { // If the new size is not bigger than the old size, then the range was in // the middle of the file, and the file size did not change. Else we need to // update the filesize $this->user_set(DAV::PROP_GETCONTENTLENGTH, $newSize); } $this->storeProperties(); $this->stat = stat($this->localPath); }