Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'MDL-36538_webdav_memory_22' of git://github.com/davosmi…

…th/moodle into MOODLE_22_STABLE
  • Loading branch information...
commit f5c44fd0538d013e1def04a587ec4b18a7cb1647 2 parents 9d95db7 + 280f513
Dan Poltawski danpoltawski authored

Showing 2 changed files with 63 additions and 45 deletions. Show diff stats Hide diff stats

  1. +62 40 lib/webdavlib.php
  2. +1 5 repository/webdav/lib.php
102 lib/webdavlib.php
@@ -265,15 +265,17 @@ function mkcol($path) {
265 265 * Public method get
266 266 *
267 267 * Gets a file from a webdav collection.
268   - * @param string path, string &buffer
269   - * @return status code and &$buffer (by reference) with response data from server on success. False on error.
  268 + * @param string $path the path to the file on the webdav server
  269 + * @param string &$buffer the buffer to store the data in
  270 + * @param resource $fp optional if included, the data is written directly to this resource and not to the buffer
  271 + * @return string|bool status code and &$buffer (by reference) with response data from server on success. False on error.
270 272 */
271   - function get($path, &$buffer) {
  273 + function get($path, &$buffer, $fp = null) {
272 274 $this->_path = $this->translate_uri($path);
273 275 $this->header_unset();
274 276 $this->create_basic_request('GET');
275 277 $this->send_request();
276   - $this->get_respond();
  278 + $this->get_respond($fp);
277 279 $response = $this->process_respond();
278 280
279 281 $http_version = $response['status']['http-version'];
@@ -283,8 +285,13 @@ function get($path, &$buffer) {
283 285 // seems to be http ... proceed
284 286 // We expect a 200 code
285 287 if ($response['status']['status-code'] == 200 ) {
286   - $this->_error_log('returning buffer with ' . strlen($response['body']) . ' bytes.');
287   - $buffer = $response['body'];
  288 + if (!is_null($fp)) {
  289 + $stat = fstat($fp);
  290 + $this->_error_log('file created with ' . $stat['size'] . ' bytes.');
  291 + } else {
  292 + $this->_error_log('returning buffer with ' . strlen($response['body']) . ' bytes.');
  293 + $buffer = $response['body'];
  294 + }
288 295 }
289 296 return $response['status']['status-code'];
290 297 }
@@ -387,27 +394,24 @@ function put_file($path, $filename) {
387 394 * Gets a file from a collection into local filesystem.
388 395 *
389 396 * fopen() is used.
390   - * @param string srcpath, string localpath
391   - * @return true on success. false on error.
  397 + * @param string $srcpath
  398 + * @param string $localpath
  399 + * @return bool true on success. false on error.
392 400 */
393 401 function get_file($srcpath, $localpath) {
394 402
395   - if ($this->get($srcpath, $buffer)) {
396   - // convert utf-8 filename to iso-8859-1
  403 + $localpath = $this->utf_decode_path($localpath);
397 404
398   - $localpath = $this->utf_decode_path($localpath);
399   -
400   - $handle = fopen ($localpath, 'w');
401   - if ($handle) {
402   - fwrite($handle, $buffer);
403   - fclose($handle);
  405 + $handle = fopen($localpath, 'wb');
  406 + if ($handle) {
  407 + $unused = '';
  408 + $ret = $this->get($srcpath, $unused, $handle);
  409 + fclose($handle);
  410 + if ($ret) {
404 411 return true;
405   - } else {
406   - return false;
407 412 }
408   - } else {
409   - return false;
410 413 }
  414 + return false;
411 415 }
412 416
413 417 /**
@@ -1444,8 +1448,9 @@ private function send_request() {
1444 1448 * This routine is the weakest part of this class, because it very depends how php does handle a socket stream.
1445 1449 * If the stream is blocked for some reason php is blocked as well.
1446 1450 * @access private
  1451 + * @param resource $fp optional the file handle to write the body content to (stored internally in the '_body' if not set)
1447 1452 */
1448   - private function get_respond() {
  1453 + private function get_respond($fp = null) {
1449 1454 $this->_error_log('get_respond()');
1450 1455 // init vars (good coding style ;-)
1451 1456 $buffer = '';
@@ -1506,7 +1511,8 @@ private function get_respond() {
1506 1511 $read = 0;
1507 1512 // Reading the chunk in one bite is not secure, we read it byte by byte.
1508 1513 while ($read < $chunk_size) {
1509   - $buffer .= fread($this->sock, 1);
  1514 + $chunk = fread($this->sock, 1);
  1515 + self::update_file_or_buffer($chunk, $fp, $buffer);
1510 1516 $read++;
1511 1517 }
1512 1518 }
@@ -1522,21 +1528,20 @@ private function get_respond() {
1522 1528 if ($matches[1] <= $max_chunk_size ) {
1523 1529 // only read something if Content-Length is bigger than 0
1524 1530 if ($matches[1] > 0 ) {
1525   - $buffer = fread($this->sock, $matches[1]);
1526   - $loadsize = strlen($buffer);
  1531 + $chunk = fread($this->sock, $matches[1]);
  1532 + $loadsize = strlen($chunk);
1527 1533 //did we realy get the full length?
1528 1534 if ($loadsize < $matches[1]) {
1529 1535 $max_chunk_size = $loadsize;
1530 1536 do {
1531   - $mod = $max_chunk_size % ($matches[1] - strlen($buffer));
1532   - $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - strlen($buffer));
1533   - $buffer .= fread($this->sock, $chunk_size);
1534   - $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . strlen($buffer));
  1537 + $mod = $max_chunk_size % ($matches[1] - strlen($chunk));
  1538 + $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - strlen($chunk));
  1539 + $chunk .= fread($this->sock, $chunk_size);
  1540 + $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . strlen($chunk));
1535 1541 } while ($mod == $max_chunk_size);
1536   - break;
1537   - } else {
1538   - break;
1539 1542 }
  1543 + self::update_file_or_buffer($chunk, $fp, $buffer);
  1544 + break;
1540 1545 } else {
1541 1546 $buffer = '';
1542 1547 break;
@@ -1545,20 +1550,23 @@ private function get_respond() {
1545 1550
1546 1551 // data is to big to handle it as one. Get it chunk per chunk...
1547 1552 //trying to get the full length of max_chunk_size
1548   - $buffer = fread($this->sock, $max_chunk_size);
1549   - $loadsize = strlen($buffer);
  1553 + $chunk = fread($this->sock, $max_chunk_size);
  1554 + $loadsize = strlen($chunk);
  1555 + self::update_file_or_buffer($chunk, $fp, $buffer);
1550 1556 if ($loadsize < $max_chunk_size) {
1551 1557 $max_chunk_size = $loadsize;
1552 1558 }
1553 1559 do {
1554   - $mod = $max_chunk_size % ($matches[1] - strlen($buffer));
1555   - $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - strlen($buffer));
1556   - $buffer .= fread($this->sock, $chunk_size);
1557   - $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . strlen($buffer));
  1560 + $mod = $max_chunk_size % ($matches[1] - $loadsize);
  1561 + $chunk_size = ($mod == $max_chunk_size ? $max_chunk_size : $matches[1] - $loadsize);
  1562 + $chunk = fread($this->sock, $chunk_size);
  1563 + self::update_file_or_buffer($chunk, $fp, $buffer);
  1564 + $loadsize += strlen($chunk);
  1565 + $this->_error_log('mod: ' . $mod . ' chunk: ' . $chunk_size . ' total: ' . $loadsize);
1558 1566 } while ($mod == $max_chunk_size);
1559   - $loadsize = strlen($buffer);
1560 1567 if ($loadsize < $matches[1]) {
1561   - $buffer .= fread($this->sock, $matches[1] - $loadsize);
  1568 + $chunk = fread($this->sock, $matches[1] - $loadsize);
  1569 + self::update_file_or_buffer($chunk, $fp, $buffer);
1562 1570 }
1563 1571 break;
1564 1572
@@ -1574,7 +1582,8 @@ private function get_respond() {
1574 1582 $this->_error_log('reading until feof...' . $header);
1575 1583 socket_set_timeout($this->sock, 0, 0);
1576 1584 while (!feof($this->sock)) {
1577   - $buffer .= fread($this->sock, 4096);
  1585 + $chunk = fread($this->sock, 4096);
  1586 + self::update_file_or_buffer($chunk, $fp, $buffer);
1578 1587 }
1579 1588 // renew the socket timeout...does it do something ???? Is it needed. More debugging needed...
1580 1589 socket_set_timeout($this->sock, $this->_socket_timeout, 0);
@@ -1588,6 +1597,19 @@ private function get_respond() {
1588 1597
1589 1598 }
1590 1599
  1600 + /**
  1601 + * Write the chunk to the file if $fp is set, otherwise append the data to the buffer
  1602 + * @param string $chunk the data to add
  1603 + * @param resource $fp the file handle to write to (or null)
  1604 + * @param string &$buffer the buffer to append to (if $fp is null)
  1605 + */
  1606 + static private function update_file_or_buffer($chunk, $fp, &$buffer) {
  1607 + if ($fp) {
  1608 + fwrite($fp, $chunk);
  1609 + } else {
  1610 + $buffer .= $chunk;
  1611 + }
  1612 + }
1591 1613
1592 1614 /**
1593 1615 * Private method process_respond
6 repository/webdav/lib.php
@@ -65,16 +65,12 @@ public function check_login() {
65 65 return true;
66 66 }
67 67 public function get_file($url, $title) {
68   - global $CFG;
69 68 $url = urldecode($url);
70 69 $path = $this->prepare_file($title);
71   - $buffer = '';
72 70 if (!$this->dav->open()) {
73 71 return false;
74 72 }
75   - $this->dav->get($url, $buffer);
76   - $fp = fopen($path, 'wb');
77   - fwrite($fp, $buffer);
  73 + $this->dav->get_file($url, $path);
78 74 return array('path'=>$path);
79 75 }
80 76 public function global_search() {

0 comments on commit f5c44fd

Please sign in to comment.
Something went wrong with that request. Please try again.