00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 require_once 'HTTP/WebDAV/Server.php';
00023 require_once 'diogenes/diogenes.misc.inc.php';
00024 require_once 'diogenes.webdav.logger.inc.php';
00025 require_once 'Barrel.php';
00026 require_once 'Barrel/Page.php';
00027
00032 class DiogenesWebDAV extends HTTP_WebDAV_Server
00033 {
00035 var $barrel;
00036
00038 var $debug_handle;
00039
00041 var $debug_capture;
00042
00046 function DiogenesWebDAV()
00047 {
00048 global $globals;
00049
00050
00051 $this->HTTP_WebDAV_Server();
00052
00053
00054
00055 $_SESSION['session'] = new $globals->session;
00056
00057 $this->debug_capture = $globals->debugwebdav_capture;
00058
00059
00060 if ($globals->debugwebdav)
00061 {
00062 $this->debugInit($globals->debugwebdav);
00063 register_shutdown_function(array(&$this, 'debugClose'));
00064 }
00065
00066 }
00067
00068
00075 function _urlencode($path, $for_html=false) {
00076 if ($this->barrel->vhost) {
00077 $path = preg_replace("/^(.*)\/site\/{$this->barrel->alias}\/(.*)/", "/\$2",$path);
00078 }
00079 return parent::_urlencode($path, $for_html);
00080 }
00081
00082
00090 function check_auth($type, $user, $pass)
00091 {
00092 global $globals;
00093
00094
00095 if (!$_SESSION['session']->doAuthWebDAV($user,$pass))
00096 return false;
00097
00098
00099 $_SESSION['session']->setBarrelPerms($this->barrel->alias);
00100
00101 return true;
00102 }
00103
00104
00105
00111 function copy($options)
00112 {
00113
00114 return "403 Forbidden";
00115 }
00116
00117
00118
00119
00123 function debugInit($debugfile)
00124 {
00125 if (empty($debugfile))
00126 return;
00127
00128
00129 if ($fp = fopen($debugfile, "a"))
00130 {
00131 $this->debug_handle = $fp;
00132 }
00133 }
00134
00135
00139 function debug($func, $msg)
00140 {
00141 if (isset($this->debug_handle))
00142 {
00143 $out = sprintf("[%s] %s : %s\n",date("H:i:s"), $func, $msg);
00144 fputs($this->debug_handle, $out);
00145 }
00146 }
00147
00148
00152 function debugClose()
00153 {
00154 if (isset($this->debug_handle))
00155 {
00156 fclose($this->debug_handle);
00157 }
00158 }
00159
00160
00166 function delete($options)
00167 {
00168 global $globals;
00169 $pathinfo = $this->parsePathInfo($options["path"]);
00170
00171
00172 $pid = $this->barrel->getPID($pathinfo['dir']);
00173 if (!$pid || !$bpage = Diogenes_Barrel_Page::fromDb($this->barrel, $pid))
00174 {
00175 $this->debug('delete', "Could not find directory {$pathinfo['dir']}");
00176 return false;
00177 }
00178
00179
00180 if (!$_SESSION['session']->hasPerms($bpage->props['wperms']))
00181 {
00182 $this->debug('delete', "Insufficient privileges (needed : {$bpage->props['wperms']})");
00183 return "403 Forbidden";
00184 }
00185
00186
00187 $rcs = $this->getRcs();
00188 $rcs->del($pid,$pathinfo['file']);
00189 return "204 No content";
00190 }
00191
00192
00199 function fileinfo($fspath, $uri)
00200 {
00201 global $globals;
00202
00203 $file = array();
00204 $file["path"]= $uri;
00205
00206 $file["props"][] = $this->mkprop("displayname", strtoupper($uri));
00207
00208 $file["props"][] = $this->mkprop("creationdate", filectime($fspath));
00209 $file["props"][] = $this->mkprop("getlastmodified", filemtime($fspath));
00210
00211 if (is_dir($fspath)) {
00212 $file["props"][] = $this->mkprop("getcontentlength", 0);
00213 $file["props"][] = $this->mkprop("resourcetype", "collection");
00214 $file["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
00215 } else {
00216 $file["props"][] = $this->mkprop("resourcetype", "");
00217 $file["props"][] = $this->mkprop("getcontentlength", filesize($fspath));
00218 if (is_readable($fspath)) {
00219 $file["props"][] = $this->mkprop("getcontenttype", get_mime_type($fspath));
00220 } else {
00221 $file["props"][] = $this->mkprop("getcontenttype", "application/x-non-readable");
00222 }
00223 }
00224 return $file;
00225 }
00226
00227
00233 function GET(&$options)
00234 {
00235 global $globals;
00236 $pathinfo = $this->parsePathInfo($options["path"]);
00237
00238
00239 $pid = $this->barrel->getPID($pathinfo['dir']);
00240 if (!$pid || !$bpage = Diogenes_Barrel_Page::fromDb($this->barrel, $pid))
00241 {
00242 $this->debug('PROPFIND', "Could not find directory {$pathinfo['dir']}");
00243 return false;
00244 }
00245
00246
00247 if (!$_SESSION['session']->hasPerms($bpage->props['perms']))
00248 {
00249 $this->debug('PROPFIND', "Insufficient privileges (needed : {$bpage->props['perms']})");
00250 return "403 Forbidden";
00251 }
00252
00253
00254 $fspath = $this->barrel->spool->spoolPath($pid,$pathinfo['file']);
00255 if (file_exists($fspath)) {
00256 $options['mimetype'] = get_mime_type($fspath);
00257
00258
00259
00260
00261 $options['mtime'] = filemtime($fspath);
00262 $options['size'] = filesize($fspath);
00263
00264
00265 $options['stream'] = fopen($fspath, "r");
00266
00267 return true;
00268 } else {
00269 return false;
00270 }
00271 }
00272
00273
00277 function getRcs()
00278 {
00279 global $globals;
00280 return new $globals->rcs($this,$this->barrel->alias,$_SESSION['session']->username);
00281 }
00282
00283
00289 function http_PROPFIND()
00290 {
00291 $this->debug('http_PROPFIND', "called");
00292 return parent::http_PROPFIND();
00293 }
00294
00295
00302 function info($msg) {
00303
00304 }
00305
00306
00314 function kill($msg) {
00315 $this->http_status("400 Error");
00316 exit;
00317 }
00318
00319
00328 function log($action,$data) {
00329 if (isset($_SESSION['log']) && is_object($_SESSION['log']))
00330 $_SESSION['log']->log($action,$data);
00331 }
00332
00333
00339 function MKCOL($options)
00340 {
00341
00342 return "403 Forbidden";
00343 }
00344
00345
00351 function move($options)
00352 {
00353
00354 return "403 Forbidden";
00355 }
00356
00357
00364 function parsePathInfo($path) {
00365 global $globals;
00366
00367 $this->debug('parsePathInfo', "path : $path");
00368 if (empty($path) || !preg_match("/^\/([^\/]+)\/webdav(\/((.+)\/)?([^\/]*))?$/",$path,$asplit))
00369 return false;
00370
00371 $split['alias'] = $asplit[1];
00372 $split['dir'] = isset($asplit[4]) ? $asplit[4] : "";
00373 $split['file'] = isset($asplit[5]) ? $asplit[5] : "";
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 return $split;
00387 }
00388
00395 function PROPFIND($options, &$files)
00396 {
00397 global $globals;
00398 $pathinfo = $this->parsePathInfo($options["path"]);
00399
00400
00401 $pid = $this->barrel->getPID($pathinfo['dir']);
00402 if (!$pid || !$bpage = Diogenes_Barrel_Page::fromDb($this->barrel, $pid))
00403 {
00404 $this->debug('PROPFIND', "Could not find directory {$pathinfo['dir']}");
00405 return false;
00406 }
00407
00408
00409 if (!$_SESSION['session']->hasPerms($bpage->props['perms']))
00410 {
00411 $this->debug('PROPFIND', "Insufficient privileges (needed : {$bpage->props['perms']})");
00412 return "403 Forbidden";
00413 }
00414
00415
00416 $fspath = $this->barrel->spool->spoolPath($pid,$pathinfo['file']);
00417
00418
00419 if (!file_exists($fspath)) {
00420 return false;
00421 }
00422
00423
00424 $files["files"] = array();
00425
00426
00427 $files["files"][] = $this->fileinfo($fspath, $options["path"]);
00428
00429
00430 if (!$pathinfo['file'] && !empty($options["depth"])) {
00431
00432
00433 if (substr($options["path"],-1) != "/") {
00434 $options["path"] .= "/";
00435 }
00436
00437
00438 $res = $globals->db->query("select PID,location from {$this->barrel->table_page} where parent='$pid'");
00439 while (list($dpid,$dloc) = mysql_fetch_row($res)) {
00440 $dpath = $this->barrel->spool->spoolPath($dpid);
00441 $duri = $options["path"].$dloc;
00442 $files["files"][] = $this->fileinfo($dpath, $duri);
00443 }
00444 mysql_free_result($res);
00445
00446
00447 $handle = @opendir($fspath);
00448 if ($handle) {
00449
00450 while ($filename = readdir($handle)) {
00451 if ($filename != "." && $filename != "..") {
00452 $fpath = $this->barrel->spool->spoolPath($pid,$filename);
00453 $furi = $options["path"].$filename;
00454 if (!is_dir($fpath))
00455 $files["files"][] = $this->fileinfo ($fpath, $furi);
00456 }
00457 }
00458 }
00459 }
00460
00461
00462 return true;
00463 }
00464
00470 function proppatch(&$options)
00471 {
00472 global $prefs, $tab;
00473
00474 $msg = "";
00475
00476 $path = $options["path"];
00477
00478 $dir = dirname($path)."/";
00479 $base = basename($path);
00480
00481 foreach($options["props"] as $key => $prop) {
00482 if($ns == "DAV:") {
00483 $options["props"][$key][$status] = "403 Forbidden";
00484 }
00485 }
00486
00487 return "";
00488 }
00489
00495 function PUT(&$options)
00496 {
00497 global $globals;
00498 $pathinfo = $this->parsePathInfo($options["path"]);
00499
00500
00501 if (!empty($options["ranges"]))
00502 return "501";
00503
00504
00505 $pid = $this->barrel->getPID($pathinfo['dir']);
00506 if (!$pid || !$bpage = Diogenes_Barrel_Page::fromDb($this->barrel, $pid))
00507 {
00508 $this->debug('PROPFIND', "Could not find directory {$pathinfo['dir']}");
00509 return false;
00510 }
00511
00512
00513 if (!$_SESSION['session']->hasPerms($bpage->props['wperms']))
00514 {
00515 $this->debug('PROPFIND', "Insufficient privileges (needed : {$bpage->props['wperms']})");
00516 return "403 Forbidden";
00517 }
00518
00519
00520 $rcs = $this->getRcs();
00521 $options["new"] = !file_exists($rcs->rcsFile($pid,$pathinfo['file']));
00522
00523
00524 $content = "";
00525 while (!feof($options["stream"])) {
00526 $content .= fread($options["stream"], 4096);
00527 }
00528
00529
00530 if ($pathinfo['file'] == $globals->htmlfile)
00531 $content = $rcs->importHtmlString($content);
00532
00533
00534 if (!$rcs->commit($pid,$pathinfo['file'],$content,"WebDAV PUT of {$pathinfo['file']}"))
00535 return "400 Error";
00536
00537
00538 if ($globals->word_import && $pathinfo['file'] == $globals->wordfile) {
00539 $myfile = $this->barrel->spool->spoolPath($pid,$globals->wordfile);
00540 $rcs->importWordFile($pid, $globals->htmlfile, $myfile);
00541 }
00542
00543 return $options["new"] ? "201 Created" : "204 No Content";
00544 }
00545
00546
00550 function ServeRequest()
00551 {
00552 global $globals;
00553
00554
00555 if (!($pathinfo = $this->parsePathInfo($_SERVER['PATH_INFO'])))
00556 {
00557 $this->http_status("404 not found");
00558 exit;
00559 }
00560
00561
00562 $this->barrel = new Diogenes_Barrel($pathinfo['alias'], $this);
00563 if (!$this->barrel->alias)
00564 {
00565 $this->debug("Could not find barrel '{$pathinfo['alias']}'");
00566 $this->http_status("404 not found");
00567 exit;
00568 }
00569 $this->debug('ServeRequest', "barrel : ".$this->barrel->alias);
00570
00571
00572 $props = array( 'REQUEST_METHOD', 'REQUEST_URI', 'SCRIPT_NAME', 'PATH_INFO');
00573 foreach ($props as $prop) {
00574 $this->debug('ServeRequest', "$prop : ". $_SERVER[$prop]);
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584 $_SERVER['SCRIPT_NAME'] = substr($_SERVER['REQUEST_URI'], 0, - strlen($_SERVER['PATH_INFO']));
00585 $this->debug('ServeRequest', "SCRIPT_NAME(mod) : ". $_SERVER['SCRIPT_NAME']);
00586
00587
00588 ob_start();
00589
00590
00591 parent::ServeRequest();
00592
00593
00594 $out = ob_get_contents();
00595 ob_end_clean();
00596
00597
00598 if ($this->barrel->vhost)
00599 {
00600 $ohref = (@$_SERVER["HTTPS"] === "on" ? "https:" : "http:");
00601 $ohref.= "//".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
00602 $ohref.= "/" . $this->barrel->alias . "/webdav/";
00603 $this->debug('ServeRequest', "ohref : ".$ohref);
00604
00605 $vhref = (@$_SERVER['HTTPS'] === "on" ? "https:" : "http:");
00606 $vhref.= "//".$this->barrel->vhost . "/webdav/";
00607 $this->debug('ServeRequest', "vhref : ".$vhref);
00608
00609 $out = str_replace($ohref, $vhref, $out);
00610 $out = str_replace('<D:displayname>/'.strtoupper($this->barrel->alias).'/WEBDAV/', '<D:displayname>/WEBDAV/', $out);
00611 }
00612
00613
00614 echo $out;
00615
00616
00617 if ($this->debug_capture)
00618 {
00619 $this->debug('ServeRequest', "out\n--- begin --\n$out--- end ---\n");
00620 }
00621
00622 }
00623
00624
00625 }
00626
00627 ?>