"improved memory usage to eg. allow to use much bigger addressbooks (with 96MB memory_limit 7500 instead of 2000 contacts) by:

- having a single foreach loop (instead of two)
- using references, to NOT copy files array
- going back to chunked encoding (requires change in header.inc.php, see header.inc.php.template)"
This commit is contained in:
Ralf Becker 2009-10-16 07:54:06 +00:00
parent e4e7e4bc36
commit de766ba416

View File

@ -598,16 +598,22 @@ class HTTP_WebDAV_Server
// Microsoft Clients need this special namespace for date and time values // Microsoft Clients need this special namespace for date and time values
$ns_defs = "xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\""; $ns_defs = "xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\"";
// now we generate the reply header ...
$this->http_status("207 Multi-Status");
header('Content-Type: text/xml; charset="utf-8"');
// ... and payload
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
echo "<D:multistatus xmlns:D=\"DAV:\">\n";
// now we loop over all returned file entries // now we loop over all returned file entries
foreach ($files["files"] as $filekey => $file) { foreach ($files["files"] as $filekey => &$file) {
// nothing to do if no properties were returend for a file // nothing to do if no properties were returend for a file
if (!isset($file["props"]) || !is_array($file["props"])) { if (isset($file["props"]) && is_array($file["props"])) {
continue;
}
// now loop over all returned properties // now loop over all returned properties
foreach ($file["props"] as $key => $prop) { foreach ($file["props"] as $key => &$prop) {
// as a convenience feature we do not require that user handlers // as a convenience feature we do not require that user handlers
// restrict returned properties to the requested ones // restrict returned properties to the requested ones
// here we strip all unrequested entries out of the response // here we strip all unrequested entries out of the response
@ -622,7 +628,7 @@ class HTTP_WebDAV_Server
case "names": case "names":
// only the names of all existing properties were requested // only the names of all existing properties were requested
// so we remove all values // so we remove all values
unset($files["files"][$filekey]["props"][$key]["val"]); unset($file[$filekey]["props"][$key]["val"]);
break; break;
default: default:
@ -639,7 +645,7 @@ class HTTP_WebDAV_Server
// unset property and continue with next one if not found/requested // unset property and continue with next one if not found/requested
if (!$found) { if (!$found) {
$files["files"][$filekey]["props"][$key]=""; $file[$filekey]["props"][$key]="";
continue(2); continue(2);
} }
break; break;
@ -666,7 +672,7 @@ class HTTP_WebDAV_Server
$found = false; $found = false;
// check if property exists in result // check if property exists in result
foreach ($file["props"] as $prop) { foreach ($file["props"] as &$prop) {
if ( $reqprop["name"] == $prop["name"] if ( $reqprop["name"] == $prop["name"]
&& @$reqprop["xmlns"] == $prop["ns"]) { && @$reqprop["xmlns"] == $prop["ns"]) {
$found = true; $found = true;
@ -677,13 +683,13 @@ class HTTP_WebDAV_Server
if (!$found) { if (!$found) {
if ($reqprop["xmlns"]==="DAV:" && $reqprop["name"]==="lockdiscovery") { if ($reqprop["xmlns"]==="DAV:" && $reqprop["name"]==="lockdiscovery") {
// lockdiscovery is handled by the base class // lockdiscovery is handled by the base class
$files["files"][$filekey]["props"][] $file[$filekey]["props"][]
= $this->mkprop("DAV:", = $this->mkprop("DAV:",
"lockdiscovery", "lockdiscovery",
$this->lockdiscovery($files["files"][$filekey]['path'])); $this->lockdiscovery($file[$filekey]['path']));
} else { } else {
// add empty value for this property // add empty value for this property
$files["files"][$filekey]["noprops"][] = $file[$filekey]["noprops"][] =
$this->mkprop($reqprop["xmlns"], $reqprop["name"], ""); $this->mkprop($reqprop["xmlns"], $reqprop["name"], "");
// register property namespace if not known yet // register property namespace if not known yet
@ -697,19 +703,6 @@ class HTTP_WebDAV_Server
} }
} }
} }
// now we generate the reply header ...
$this->http_status("207 Multi-Status");
header('Content-Type: text/xml; charset="utf-8"');
// we buffer the output to be able to send a Content-Length header, as some clients dont understand chunked encoding
ob_start();
// ... and payload
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
echo "<D:multistatus xmlns:D=\"DAV:\">\n";
foreach ($files["files"] as $file) {
// ignore empty or incomplete entries // ignore empty or incomplete entries
if (!is_array($file) || empty($file) || !isset($file["path"])) continue; if (!is_array($file) || empty($file) || !isset($file["path"])) continue;
$path = $file['path']; $path = $file['path'];
@ -721,7 +714,6 @@ class HTTP_WebDAV_Server
collections end in a slash, this should be done in here collections end in a slash, this should be done in here
by checking the resource attribute */ by checking the resource attribute */
// path needs to be urlencoded (only basic version of this class!) // path needs to be urlencoded (only basic version of this class!)
//$href = $this->_mergePathes($this->base_uri, $path);
$href = $this->_urlencode($this->_mergePathes($this->base_uri, $path)); $href = $this->_urlencode($this->_mergePathes($this->base_uri, $path));
echo " <D:href>$href</D:href>\n"; echo " <D:href>$href</D:href>\n";
@ -731,7 +723,7 @@ class HTTP_WebDAV_Server
echo " <D:propstat>\n"; echo " <D:propstat>\n";
echo " <D:prop>\n"; echo " <D:prop>\n";
foreach ($file["props"] as $key => $prop) { foreach ($file["props"] as $key => &$prop) {
if (!is_array($prop)) continue; if (!is_array($prop)) continue;
if (!isset($prop["name"])) continue; if (!isset($prop["name"])) continue;
@ -869,7 +861,7 @@ class HTTP_WebDAV_Server
echo " <D:propstat>\n"; echo " <D:propstat>\n";
echo " <D:prop>\n"; echo " <D:prop>\n";
foreach ($file["noprops"] as $key => $prop) { foreach ($file["noprops"] as $key => &$prop) {
if ($prop["ns"] == "DAV:") { if ($prop["ns"] == "DAV:") {
echo " <D:$prop[name]/>\n"; echo " <D:$prop[name]/>\n";
} else if ($prop["ns"] == "") { } else if ($prop["ns"] == "") {
@ -888,10 +880,6 @@ class HTTP_WebDAV_Server
} }
echo "</D:multistatus>\n"; echo "</D:multistatus>\n";
// sending the Content-Lenght header, before flushing the buffer
header('Content-Length: '.ob_get_length());
ob_end_flush();
} }