Example #1
0
 /**
  * Checks and handles MKCOL request
  * @param DAV_Resource $resource
  * @return void
  * @throws DAV_Status
  */
 protected function handle($resource)
 {
     if ($resource) {
         if ($resource->isVisible()) {
             throw new DAV_Status(DAV::HTTP_METHOD_NOT_ALLOWED);
         }
         throw DAV::forbidden();
     }
     $resource = DAV::$REGISTRY->resource(dirname(DAV::getPath()));
     if (!$resource or !$resource->isVisible()) {
         throw new DAV_Status(DAV::HTTP_CONFLICT, 'Unable to MKCOL in unknown resource');
     }
     if (!$resource instanceof DAV_Collection) {
         throw new DAV_Status(DAV::HTTP_METHOD_NOT_ALLOWED);
     }
     if (0 < (int) @$_SERVER['CONTENT_LENGTH']) {
         throw new DAV_Status(DAV::HTTP_UNSUPPORTED_MEDIA_TYPE);
     }
     $resource->assertLock();
     $resource->method_MKCOL(basename(DAV::getPath()));
     DAV::redirect(DAV::HTTP_CREATED, DAV::getPath());
 }
Example #2
0
 public function method_POST(&$headers)
 {
     $this->init_props();
     // For all POST requests, you need to send a POST field 'password' with the current password
     if (!isset($_POST['password']) || !$this->check_password($_POST['password'])) {
         throw DAV::forbidden();
     }
     if (isset($_POST['verification_code'])) {
         // Now verify the e-mail address
         if (!$this->verify_email_address($_POST['verification_code'])) {
             throw DAV::forbidden();
         }
         DAV::redirect(DAV::HTTP_SEE_OTHER, $this->path);
         return;
     } elseif (isset($_POST['new_password'])) {
         $this->set_password($_POST['new_password']);
         DAV::redirect(DAV::HTTP_SEE_OTHER, $this->path);
         return;
     }
     throw new DAV_Status(DAV::HTTP_BAD_REQUEST);
 }
Example #3
0
 public function method_POST(&$headers)
 {
     $displayname = $_POST['displayname'];
     $description = $_POST['description'];
     $group_name = $_POST['group_name'];
     $user_sponsor = BeeHub::getAuth()->current_user()->user_prop(BeeHub::PROP_SPONSOR);
     // If you don't have a (default) sponsor, you're not allowed to add a group
     if (empty($user_sponsor)) {
         throw DAV::forbidden("Only users with a sponsor are allowed to create groups");
     }
     // Group name must be one of the following characters a-zA-Z0-9_-., starting with an alphanumeric character and must be between 1 and 255 characters long and can't be one of the forbidden names
     if (empty($displayname) || in_array(strtolower($group_name), BeeHub::$FORBIDDEN_GROUP_NAMES) || !preg_match('/^[a-zA-Z0-9]{1}[a-zA-Z0-9_\\-\\.]{0,254}$/D', $group_name)) {
         throw new DAV_Status(DAV::HTTP_BAD_REQUEST, 'Group name has the wrong format. The name can be a maximum of 255 characters long and should start with an alphanumeric character, followed by alphanumeric characters or one of the following: _-.');
     }
     // Check if the group name doesn't exist
     $collection = BeeHub::getNoSQL()->groups;
     $result = $collection->findOne(array('name' => $group_name), array('name' => true));
     if (!is_null($result)) {
         // Duplicate key: bad request!
         throw new DAV_Status(DAV::HTTP_CONFLICT, "Group name already exists, please choose a different group name!");
     }
     $groupdir = DAV::unslashify(BeeHub::$CONFIG['environment']['datadir']) . DIRECTORY_SEPARATOR . $group_name;
     // Check for existing groupdir
     if (file_exists($groupdir)) {
         throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR);
     }
     // Store in the database
     $collection->insert(array('name' => $group_name));
     // Fetch the group and store extra properties
     $group = DAV::$REGISTRY->resource(BeeHub::GROUPS_PATH . $group_name);
     $group->user_set(DAV::PROP_DISPLAYNAME, $displayname);
     if (!empty($description)) {
         $group->user_set(BeeHub::PROP_DESCRIPTION, $description);
     }
     $group->storeProperties();
     // Add the current user as admin of the group
     $group->change_memberships(basename($this->user_prop_current_user_principal()), BeeHub_Group::USER_ACCEPT);
     $group->change_memberships(basename($this->user_prop_current_user_principal()), BeeHub_Group::ADMIN_ACCEPT);
     $group->change_memberships(basename($this->user_prop_current_user_principal()), BeeHub_Group::SET_ADMIN);
     // And create a group directory
     if (!mkdir($groupdir)) {
         throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR);
     }
     // And create the directory in the database
     $document = array('path' => $group_name, 'depth' => 1, 'collection' => true);
     $filesCollection = BeeHub::getNoSQL()->files;
     $filesCollection->save($document);
     $groupdir_resource = DAV::$REGISTRY->resource('/' . $group_name);
     $groupdir_resource->user_set(BeeHub::PROP_SPONSOR, $user_sponsor);
     $groupdir_resource->user_set(DAV::PROP_ACL, '[["' . BeeHub::GROUPS_PATH . $group->name . '",false,["DAV: read", "DAV: write"],false]]');
     $groupdir_resource->storeProperties();
     // Group created, redirect to the group page
     DAV::redirect(DAV::HTTP_SEE_OTHER, BeeHub::GROUPS_PATH . $group->name);
 }
Example #4
0
    public function testRedirect()
    {
        $this->expectOutputString(<<<EOS
Content-Type: text/plain; charset=US-ASCII
Location: http://example.org/some/new/path
HTTP/1.1 301 Moved Permanently
http://example.org/some/new/path
EOS
);
        DAV::redirect(301, 'http://example.org/some/new/path');
    }
Example #5
0
 /**
  * Through a POST request you can create new sponsors
  * 
  * @param   array  $headers  The HTTP headers
  * @throws  DAV_Status
  * @see DAV_Resource::method_POST()
  */
 public function method_POST(&$headers)
 {
     $displayname = $_POST['displayname'];
     $description = $_POST['description'];
     $sponsor_name = $_POST['sponsor_name'];
     // Only administrators can add a sponsor
     if (!DAV::$ACLPROVIDER->wheel()) {
         throw DAV::forbidden('Only administrators are allowed to create sponsors');
     }
     // Sponsor name must be one of the following characters a-zA-Z0-9_-., starting with an alphanumeric character and must be between 1 and 255 characters long
     if (empty($displayname) || !preg_match('/^[a-zA-Z0-9]{1}[a-zA-Z0-9_\\-\\.]{0,254}$/D', $sponsor_name)) {
         throw new DAV_Status(DAV::HTTP_BAD_REQUEST, 'Sponsor name has the wrong format. The name can be a maximum of 255 characters long and should start with an alphanumeric character, followed by alphanumeric characters or one of the following: _-.');
     }
     // Check if the group name doesn't exist
     $collection = BeeHub::getNoSQL()->sponsors;
     $result = $collection->findOne(array('name' => $sponsor_name), array('name' => true));
     if (!is_null($result)) {
         // Duplicate key: bad request!
         throw new DAV_Status(DAV::HTTP_CONFLICT, "Sponsor name already exists, please choose a different sponsor name!");
     }
     // Store in the database
     $collection->insert(array('name' => $sponsor_name));
     // Fetch the sponsor and store extra properties
     $sponsor = DAV::$REGISTRY->resource(BeeHub::SPONSORS_PATH . $sponsor_name);
     $sponsor->user_set(DAV::PROP_DISPLAYNAME, $displayname);
     if (!empty($description)) {
         $sponsor->user_set(BeeHub::PROP_DESCRIPTION, $description);
     }
     $sponsor->storeProperties();
     // Add the current user as admin of the sponsor
     $sponsor->change_memberships(basename($this->user_prop_current_user_principal()), BeeHub_Sponsor::ADMIN_ACCEPT);
     $sponsor->change_memberships(basename($this->user_prop_current_user_principal()), BeeHub_Sponsor::SET_ADMIN);
     // Sponsor created, redirect to the sponsor page
     DAV::redirect(DAV::HTTP_SEE_OTHER, BeeHub::SPONSORS_PATH . $sponsor->name);
 }
Example #6
0
 /**
  * Authenticates the user through one of the authentication mechanisms.
  * @param  boolean $requireAuth  If set to false and authentication fails,
  *   the user will continue as an unauthenticated user. If set to true
  *   (default), status 401 UNAUTHORIZED will be returned upon authentication
  *   failure.
  * @param  boolean  $allowDoubleLogin  TODO documentation
  */
 public function handle_authentication($requireAuth = true, $allowDoubleLogin = false)
 {
     // We start with assuming nobody is logged in
     $this->set_user(null);
     $this->SURFconext = false;
     if (isset($_GET['logout'])) {
         if ($this->simpleSAML_authentication->isAuthenticated()) {
             $this->simpleSAML_authentication->logout();
         }
         if (!empty($_SERVER['HTTPS'])) {
             DAV::redirect(DAV::HTTP_SEE_OTHER, BeeHub::urlbase(false) . '/system/');
             return;
         }
     }
     if (isset($_SERVER['PHP_AUTH_PW'])) {
         if (!$allowDoubleLogin) {
             if ($this->simpleSAML_authentication->isAuthenticated()) {
                 // You can't be logged in through SURFconext and HTTP Basic at the same time!
                 $this->simpleSAML_authentication->logout();
             }
             if ('conext' === @$_GET['login']) {
                 throw new DAV_Status(DAV::HTTP_BAD_REQUEST, "You are already logged in using your username/password. Therefore you are not allowed to login using SURFconext. Unfortunately the only way to logout with your username and password is to close all browser windows. Hit the 'back' button in your browser and login using username/password.");
             }
         }
         // The user already sent username and password: check them!
         try {
             $user = BeeHub::user($_SERVER['PHP_AUTH_USER']);
             $password_verified = $user->check_password($_SERVER['PHP_AUTH_PW']);
         } catch (DAV_Status $status) {
             if ($status->getCode() === DAV::HTTP_FORBIDDEN) {
                 $password_verified = false;
             }
         }
         if (!$password_verified) {
             // If authentication fails, respond accordingly
             if ('passwd' === @$_GET['login'] || $requireAuth) {
                 // User could not be authenticated with supplied credentials, but we
                 // require authentication, so we ask again!
                 $this->unauthorized();
             }
         } else {
             // Authentication succeeded: store credentials!
             $this->set_user($_SERVER['PHP_AUTH_USER']);
         }
         // end of: if (user sent username/passwd)
     } elseif ('passwd' !== @$_GET['login'] && $this->simpleSAML_authentication->isAuthenticated()) {
         $surfId = $this->simpleSAML_authentication->getAuthData("saml:sp:NameID");
         $surfId = $surfId['Value'];
         $collection = BeeHub::getNoSQL()->users;
         $result = $collection->findOne(array('surfconext_id' => $surfId), array('name' => true));
         if (!is_null($result)) {
             // We found a user, this is the one that's logged in!
             $this->SURFconext = true;
             $this->set_user($result['name']);
         } elseif (rawurldecode($_SERVER['REQUEST_URI']) !== BeeHub::USERS_PATH) {
             throw new DAV_Status(DAV::HTTP_TEMPORARY_REDIRECT, BeeHub::urlbase(true) . BeeHub::USERS_PATH);
         }
     } elseif ('conext' === @$_GET['login']) {
         // We don't know this SURFconext ID, this is a new user
         $this->simpleSAML_authentication->login();
     } elseif ('passwd' === @$_GET['login'] || $requireAuth) {
         // If the user didn't send any credentials, but we require authentication, ask for it!
         $this->unauthorized();
     }
     // If the current user is logged in, but has no verified e-mail address.
     // He/she is not authorized to do anything, but will get a message that we
     // want a verified e-mail address. Although he has to be able to verify
     // his e-mail address of course (so GET and POST on /system/users/<name>
     // is allowed)
     $user = $this->current_user();
     if (!is_null($user)) {
         // Update the http://beehub.nl/ last-activity property
         $user->user_set(BeeHub::PROP_LAST_ACTIVITY, date('Y-m-d\\TH:i:sP'));
         $user->storeProperties();
         $email = $user->prop(BeeHub::PROP_EMAIL);
         if (empty($email) && DAV::unslashify(DAV::getPath()) != DAV::unslashify($user->path)) {
             $message = file_get_contents(dirname(dirname(__FILE__)) . '/views/error_no_verified_email.html');
             $message = str_replace('%USER_PATH%', BeeHub::urlbase(true) . DAV::encodeURIFullPath($user->path), $message);
             BeeHub::htmlError($message, DAV::HTTP_FORBIDDEN);
         }
     }
 }
Example #7
0
 /**
  * Handles the PUT request
  *
  * This method checks whether the PUT request is valid and, if so, writes the
  * request body to the resource.
  *
  * @param DAV_Resource $resource
  */
 protected function handle($resource)
 {
     # This variable also flags if a new resource was created.
     $parent = null;
     if (!$resource) {
         if (!is_null($this->range_start)) {
             throw new DAV_Status(DAV::HTTP_NOT_FOUND);
         }
         $parent = DAV::$REGISTRY->resource(dirname(DAV::getPath()));
         if (!$parent || !$parent instanceof DAV_Collection) {
             throw new DAV_Status(DAV::HTTP_CONFLICT, 'Unable to PUT file in non-existing collection.');
         }
         $parent->assertLock();
         $parent->create_member(basename(DAV::getPath()));
         $resource = DAV::$REGISTRY->resource(DAV::getPath());
     } elseif ($resource instanceof DAV_Collection) {
         throw new DAV_Status(DAV::HTTP_METHOD_NOT_ALLOWED, 'Method PUT not supported on collections.');
     } else {
         $resource->assertLock();
     }
     if (is_null($this->range_start)) {
         try {
             if (isset($_SERVER['CONTENT_TYPE']) && 'application/octet-stream' !== $_SERVER['CONTENT_TYPE']) {
                 $resource->set_getcontenttype($_SERVER['CONTENT_TYPE']);
             } else {
                 $resource->set_getcontenttype(null);
             }
         } catch (DAV_Status $e) {
         }
         if (isset($_SERVER['HTTP_CONTENT_LANGUAGE'])) {
             try {
                 $resource->set_getcontentlanguage($_SERVER['HTTP_CONTENT_LANGUAGE']);
             } catch (DAV_Status $e) {
             }
         }
         $resource->storeProperties();
         $input = fopen('php://input', 'r');
         try {
             $resource->method_PUT($input);
             fclose($input);
         } catch (DAV_Status $e) {
             fclose($input);
             if ($parent) {
                 $parent->method_DELETE(basename(DAV::getPath()));
             }
             throw $e;
         }
     } else {
         $cl = $resource->user_prop_getcontentlength();
         if (!is_null($cl) && ($this->range_start > $cl or !is_null($this->range_total) && $this->range_total !== $cl)) {
             throw new DAV_Status(DAV::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE);
         }
         $input = fopen('php://input', 'r');
         try {
             $resource->method_PUT_range($input, $this->range_start, $this->range_end, $this->range_total);
             fclose($input);
         } catch (DAV_Status $e) {
             fclose($input);
             throw $e;
         }
     }
     if ($etag = $resource->prop_getetag()) {
         header('ETag: ' . htmlspecialchars_decode($etag));
     }
     if ($parent) {
         DAV::redirect(DAV::HTTP_CREATED, DAV::getPath());
     } else {
         DAV::header(array('status' => DAV::HTTP_NO_CONTENT));
     }
 }
Example #8
0
 /**
  * Sends this status to client.
  * @return void
  */
 public function output()
 {
     $status = $this->getCode();
     if ($status < 300) {
         throw new DAV_Status(DAV::HTTP_INTERNAL_SERVER_ERROR, "DAV_Status object with status {$status} " . var_export($this->getMessage(), true));
     }
     if (DAV::HTTP_UNAUTHORIZED === $status && DAV::$UNAUTHORIZED) {
         call_user_func(DAV::$UNAUTHORIZED);
         return;
     } elseif (!empty($this->conditions)) {
         $headers = array('status' => $status, 'Content-Type' => 'application/xml; charset="UTF-8"');
         if ($this->location) {
             $headers['Location'] = DAV::encodeURIFullPath($this->location);
         }
         DAV::header($headers);
         echo DAV::xml_header() . '<D:error xmlns:D="DAV:">';
         foreach ($this->conditions as $condition => $xml) {
             echo "\n<D:" . $condition;
             echo $xml ? ">{$xml}</D:{$condition}>" : "/>";
         }
         echo "\n</D:error>";
     } elseif ($this->location) {
         DAV::redirect($status, $this->location);
     } else {
         if (self::$RESPONSE_GENERATOR && in_array($_SERVER['REQUEST_METHOD'], array('GET', 'POST'))) {
             DAV::header(array('status' => $status));
             call_user_func(self::$RESPONSE_GENERATOR, $status, $this->getMessage());
         } else {
             DAV::header(array('status' => $status, 'Content-Type' => 'text/plain; charset="UTF-8"'));
             echo "HTTP/1.1 " . DAV::status_code($status) . "\n" . $this->getMessage();
         }
     }
 }
Example #9
0
}
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    require_once 'views' . DIRECTORY_SEPARATOR . 'saml_connect.php';
    exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    throw new DAV_Status(DAV::HTTP_METHOD_NOT_ALLOWED);
}
// Get some authentication info
$user = $auth->current_user();
$surfId = $simpleSaml->getAuthData("saml:sp:NameID");
$surfId = $surfId['Value'];
// You need to supply the users current password (as stored in the local database)
if (!$user->check_password($_POST['password'])) {
    throw DAV::forbidden();
}
// Unlink potential other local account linked to this SURFconext ID
$collection = BeeHub::getNoSQL()->users;
$collection->update(array('surfconext_id' => $surfId), array('$unset' => array('surfconext_id' => '', 'surfconext_description' => '')));
// And connect it to the current user
$user->user_set(BeeHub::PROP_SURFCONEXT, $surfId);
$attributes = $simpleSaml->getAttributes();
$surfconext_description = @$attributes['urn:mace:terena.org:attribute-def:schacHomeOrganization'][0];
if (empty($surfconext_description)) {
    $surfconext_description = 'Unknown account';
}
$user->user_set(BeeHub::PROP_SURFCONEXT_DESCRIPTION, $surfconext_description);
$user->storeProperties();
// Redirect to the user's profile page
DAV::redirect(DAV::HTTP_SEE_OTHER, $user->path);
Example #10
0
 /**
  * Determines whether the copy request is valid and if so, copies the resources
  * 
  * @param DAV_Resource $resource
  * @return void
  * @throws DAV_Status
  */
 protected function handle($resource)
 {
     $destination = $this->destination();
     if ($resource instanceof DAV_Collection) {
         $destination = DAV::slashify($destination);
     } else {
         // The next line is here to make the litmus test succeed. The author of
         // litmus had eir own doubts wether this is actually desirable behaviour,
         // but chose to require this behaviour anyway:
         $destination = DAV::unslashify($destination);
     }
     // Can't move the root collection:
     if ($this instanceof DAV_Request_MOVE && '/' === DAV::getPath()) {
         throw new DAV_Status(DAV::HTTP_FORBIDDEN);
     }
     // Assert proper Depth: header value:
     if (DAV::DEPTH_1 === $this->depth() or $this instanceof DAV_Request_MOVE && DAV::DEPTH_INF !== $this->depth()) {
         throw new DAV_Status(DAV::HTTP_BAD_REQUEST, 'Illegal value for Depth: header.');
     }
     // Check: Can't move a collection to one of its members.
     if ($this instanceof DAV_Request_MOVE && '/' === substr(DAV::getPath(), -1) && 0 === strpos($destination, DAV::getPath())) {
         throw new DAV_Status(DAV::HTTP_FORBIDDEN, "Can't move a collection to itself or one of its members.");
     }
     $resourceCollection = $resource->collection();
     if ($this instanceof DAV_Request_MOVE) {
         $resourceCollection->assertLock();
         $resource->assertLock();
         $resource->assertMemberLocks();
     }
     if ('/' !== $destination[0]) {
         // Copy to an external URI?
         $isCreated = $resource->method_COPY_external($destination, $this->overwrite());
         if ($this instanceof DAV_Request_MOVE && !DAV_Multistatus::active()) {
             DAV_Request_DELETE::delete($resource);
         }
         if (DAV_Multistatus::active()) {
             DAV_Multistatus::inst()->close();
         } elseif ($isCreated) {
             DAV::redirect(DAV::HTTP_CREATED, $destination);
         } else {
             DAV::header(array('status' => DAV::HTTP_NO_CONTENT));
         }
         return;
     }
     // Check: Won't move a resource to one of its parents.
     if (0 === strpos(DAV::slashify(DAV::getPath()), DAV::slashify($destination))) {
         throw new DAV_Status(DAV::HTTP_NOT_IMPLEMENTED, "Won't move or copy a resource to one of its parents.");
     }
     $destinationResource = DAV::$REGISTRY->resource($destination);
     $destinationCollection = DAV::$REGISTRY->resource(dirname($destination));
     if (!$destinationCollection) {
         throw new DAV_Status(DAV::HTTP_CONFLICT, 'Unable to COPY to unexisting destination collection');
     }
     if ($destinationResource) {
         if (!$this->overwrite()) {
             throw new DAV_Status(DAV::HTTP_PRECONDITION_FAILED);
         } else {
             $destinationResource->assertLock();
         }
     } else {
         $destinationCollection->assertLock();
     }
     if ($this instanceof DAV_Request_MOVE) {
         if (DAV::$LOCKPROVIDER) {
             foreach (DAV::$LOCKPROVIDER->memberLocks(DAV::getPath()) as $lock) {
                 DAV::$LOCKPROVIDER->unlock($lock->lockroot);
             }
             if ($lock = DAV::$LOCKPROVIDER->getlock(DAV::getPath())) {
                 DAV::$LOCKPROVIDER->unlock($lock->lockroot);
             }
         }
         $resourceCollection->method_MOVE(basename($resource->path), $destination);
     } else {
         $this->copy_recursively($resource, $destination);
     }
     #<<<<<<<<
     #// This version always returns a 207 Multistatus wrapper:
     #if (!DAV_Multistatus::active())
     #  if ( $destinationResource )
     #    DAV_Multistatus::inst()->addStatus(
     #      $resource->path,
     #      new DAV_Status( DAV::HTTP_NO_CONTENT )
     #    );
     #  else
     #    DAV_Multistatus::inst()->addStatus(
     #      $resource->path,
     #      new DAV_Status(
     #        DAV::HTTP_CREATED, DAV::path2uri($destination)
     #      )
     #    );
     #DAV_Multistatus::inst()->close();
     #========
     if (DAV_Multistatus::active()) {
         DAV_Multistatus::inst()->close();
     } elseif ($destinationResource) {
         DAV::header(array('status' => DAV::HTTP_NO_CONTENT));
     } else {
         DAV::redirect(DAV::HTTP_CREATED, $destination);
     }
     #>>>>>>>>
 }
Example #11
0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package BeeHub
 */
// Bootstrap the application
require_once '../src/beehub_bootstrap.php';
$config = BeeHub::config();
if (@$config['install']['run_install'] === 'true') {
    require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'webserver_install.php';
    exit;
}
// If a GET request on the root doesn't have this server as a referer, redirect to the homepage:
if (!isset($_GET['nosystem']) && DAV::getPath() === '/' && $_SERVER['REQUEST_METHOD'] === 'GET' && (!isset($_SERVER['HTTP_REFERER']) || $_SERVER['SERVER_NAME'] !== parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST))) {
    DAV::redirect(DAV::HTTP_SEE_OTHER, BeeHub::SYSTEM_PATH);
    return;
}
// After bootstrapping, start authentication
if (APPLICATION_ENV === BeeHub::ENVIRONMENT_TEST || !empty($_SERVER['HTTPS'])) {
    BeeHub_Auth::inst()->handle_authentication(BeeHub_Auth::is_authentication_required());
}
// And finally handle the request
$request = DAV_Request::inst();
if ($request) {
    $request->handleRequest();
}
// End of file