Skip to content
This repository was archived by the owner on Sep 10, 2021. It is now read-only.

Commit 455fc40

Browse files
committed
Merge branch '0975-HackWgetPathSupport-zach_mullen'
* 0975-HackWgetPathSupport-zach_mullen: ENH: refs #975. Use new style download URLs in our javascript calls ENH: refs #975. Append .zip to share links on multi bitstream items ENH: refs #975. Support single bitstream download as well STYLE: refs #975. Fix failing style test ENH: refs #975. Support path-style download URLs
2 parents 1442e8f + d72bf45 commit 455fc40

7 files changed

Lines changed: 122 additions & 15 deletions

File tree

core/controllers/DownloadController.php

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function indexAction()
4444
$folderIds = $this->_getParam('folders');
4545
$bitsreamid = $this->_getParam('bitstream');
4646
$sessionUser = $this->userSession->Dao;
47+
$testingMode = Zend_Registry::get('configGlobal')->environment == 'testing';
4748
if($sessionUser != null)
4849
{
4950
// Make sure this is a copy and not a reference
@@ -148,7 +149,7 @@ public function indexAction()
148149
$revision = $revisions[0];
149150
$bitstreams = $revision->getBitstreams();
150151

151-
if($this->_getParam('testingmode') == '1')
152+
if($testingMode)
152153
{
153154
$bitstreams = array($bitstreams[0]);
154155
}
@@ -167,10 +168,7 @@ public function indexAction()
167168
return;
168169
}
169170
$this->disableView();
170-
if($this->_getParam('testingmode') == '1')
171-
{
172-
$this->Component->DownloadBitstream->testingmode = true;
173-
}
171+
$this->Component->DownloadBitstream->testingmode = $testingMode;
174172
$this->Component->DownloadBitstream->download($bitstreams[0], $offset, true);
175173
}
176174
else
@@ -348,6 +346,57 @@ public function checksizeAction()
348346
}
349347
}
350348

349+
/**
350+
* This action exposes downloading a single item and should be called as
351+
* download/item/<item_id>/...
352+
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
353+
* if the content-disposition header is ignored by the user agent.
354+
*/
355+
public function itemAction()
356+
{
357+
$pathParams = UtilityComponent::extractPathParams();
358+
if(empty($pathParams))
359+
{
360+
throw new Zend_Exception('Must specify item id as a path parameter');
361+
}
362+
363+
$this->_forward('index', null, null, array('items' => $pathParams[0]));
364+
}
365+
366+
/**
367+
* This action exposes downloading a single folder and should be called as
368+
* download/folder/<folder_id>/...
369+
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
370+
* if the content-disposition header is ignored by the user agent.
371+
*/
372+
public function folderAction()
373+
{
374+
$pathParams = UtilityComponent::extractPathParams();
375+
if(empty($pathParams))
376+
{
377+
throw new Zend_Exception('Must specify folder id as a path parameter');
378+
}
379+
380+
$this->_forward('index', null, null, array('folders' => $pathParams[0]));
381+
}
382+
383+
/**
384+
* This action exposes downloading a single bitstream and should be called as
385+
* download/bitstream/<bitstream_id>/...
386+
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
387+
* if the content-disposition header is ignored by the user agent.
388+
*/
389+
public function bitstreamAction()
390+
{
391+
$pathParams = UtilityComponent::extractPathParams();
392+
if(empty($pathParams))
393+
{
394+
throw new Zend_Exception('Must specify bitstream id as a path parameter');
395+
}
396+
397+
$this->_forward('index', null, null, array('bitstream' => $pathParams[0]));
398+
}
399+
351400
/**
352401
* Render the view for the large data downloader applet
353402
* @param itemIds Comma separated list of items to download
@@ -477,7 +526,7 @@ private function _downloadEmptyItem($item)
477526
}
478527
ob_start();
479528
Zend_Loader::loadClass('ZipStream', BASE_PATH.'/library/ZipStream/');
480-
$this->_helper->viewRenderer->setNoRender();
529+
$this->disableView();
481530
if(isset($item) && $item instanceof ItemDao)
482531
{
483532
$name = $item->getName();

core/controllers/ShareController.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,30 @@ function linksAction()
353353
$type = $this->_getParam('type');
354354
$id = $this->_getParam('id');
355355

356-
$request = Zend_Controller_Front::getInstance()->getRequest();
357-
$baseUrl = $request->getScheme().'://'.$request->getHttpHost().$this->view->webroot;
356+
switch($type)
357+
{
358+
case 'folder':
359+
$dao = $this->Folder->load($id);
360+
$name = $dao->getName().'.zip';
361+
break;
362+
case 'item':
363+
$dao = $this->Item->load($id);
364+
$headRev = $this->Item->getLastRevision($dao);
365+
$name = $dao->getName();
366+
if(count($headRev->getBitstreams()) > 1)
367+
{
368+
$name .= '.zip';
369+
}
370+
break;
371+
default:
372+
throw new Zend_Exception('Invalid type', 400);
373+
}
374+
375+
$baseUrl = $this->getRequest()->getScheme().'://'.$this->getRequest()->getHttpHost().$this->view->webroot;
358376
$this->view->type = $type;
359377
$this->view->id = $id;
360378
$this->view->viewUrl = $baseUrl.'/'.$type.'/'.$id;
361-
$this->view->downloadUrl = $baseUrl.'/download?'.$type.'s='.$id;
379+
$this->view->downloadUrl = $baseUrl.'/download/'.$type.'/'.$id.'/'.urlencode($name);
362380
}
363381
}//end class
364382

core/controllers/components/UtilityComponent.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,38 @@ public function getAllModules()
9393
return $modules;
9494
}
9595

96+
/**
97+
* Helper method to extract tokens from request URI's in path form,
98+
* e.g. download/folder/123/folder_name, starting after the action name.
99+
* Returns the token as a list.
100+
*/
101+
public static function extractPathParams()
102+
{
103+
$request = Zend_Controller_Front::getInstance()->getRequest();
104+
$allTokens = preg_split('@/@', $request->getPathInfo(), NULL, PREG_SPLIT_NO_EMPTY);
105+
106+
$tokens = array();
107+
$i = 0;
108+
if($request->getModuleName() != 'default')
109+
{
110+
$i++;
111+
}
112+
if($request->getControllerName() != 'index')
113+
{
114+
$i++;
115+
}
116+
if($request->getActionName() != 'index')
117+
{
118+
$i++;
119+
}
120+
$max = count($allTokens);
121+
for(; $i < $max; $i++)
122+
{
123+
$tokens[] = $allTokens[$i];
124+
}
125+
return $tokens;
126+
}
127+
96128
/** find modules configuration in a folder */
97129
private function _initModulesConfig($dir)
98130
{

core/public/js/common/common.browser.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ midas.createAction = function (node) {
479479
}, function (text) {
480480
var retVal = $.parseJSON(text);
481481
if(retVal.action == 'download') {
482-
window.location = json.global.webroot+'/download?folders='+folderId;
482+
window.location = json.global.webroot+'/download/folder/'+folderId;
483483
}
484484
else if(retVal.action == 'promptApplet') {
485485
midas.promptDownloadApplet(folderId, '', retVal.sizeStr);
@@ -493,7 +493,7 @@ midas.createAction = function (node) {
493493
}, function (text) {
494494
var retVal = $.parseJSON(text);
495495
if(retVal.action == 'download') {
496-
window.location = json.global.webroot+'/download?items='+itemId;
496+
window.location = json.global.webroot+'/download/item/'+itemId;
497497
}
498498
else if(retVal.action == 'promptApplet') {
499499
midas.promptDownloadApplet('', itemId, retVal.sizeStr);

core/public/js/item/item.view.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ $(document).ready(function() {
55
}, function (text) {
66
var retVal = $.parseJSON(text);
77
if(retVal.action == 'download') {
8-
window.location = json.global.webroot+'/download?items='+json.item.item_id;
8+
window.location = json.global.webroot+'/download/item/'+json.item.item_id;
99
}
1010
else if(retVal.action == 'promptApplet') {
1111
var html = 'Warning: you have requested a large download ('+retVal.sizeStr+') that might take a very long time to complete.';
@@ -23,7 +23,7 @@ $(document).ready(function() {
2323
$('div.MainDialog').dialog('close');
2424
});
2525
$('input.useZipStream').unbind('click').click(function () {
26-
window.location = json.global.webroot+'/download?items='+json.item.item_id;
26+
window.location = json.global.webroot+'/download/item/'+json.item.item_id;
2727
$('div.MainDialog').dialog('close');
2828
});
2929
}

core/tests/controllers/UploadDownloadControllerTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,15 @@ function testDownloadAction()
238238

239239
$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; //must be set in order to lock active download
240240
$this->setupDatabase(array('activedownload')); //wipe any old locks
241-
$this->dispatchUrI('/download?testingmode=1&items='.$itemId, $userDao);
241+
$this->dispatchUrI('/download?items='.$itemId, $userDao);
242+
$downloadedMd5 = md5($this->getBody());
243+
244+
$this->assertEquals($actualMd5, $downloadedMd5);
245+
246+
// Test our special path-style URL endpoints for downloading single items or folders
247+
$this->resetAll();
248+
$this->setupDatabase(array('activedownload')); //wipe any old locks
249+
$this->dispatchUrI('/download/item/'.$itemId.'/', $userDao);
242250
$downloadedMd5 = md5($this->getBody());
243251

244252
$this->assertEquals($actualMd5, $downloadedMd5);

core/views/item/view.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ foreach($cssArray as $module => $list)
220220
echo ' <span name="sizeBytes">'.$bitstream->getSizebytes().'</span>';
221221
echo ' <span name="mimeType">'.$bitstream->getMimetype().'</span>';
222222
echo ' </div>';
223-
echo '<a href="'.$this->webroot.'/download?bitstream='.$bitstream->getKey().'">';
223+
echo '<a href="'.$this->webroot.'/download/bitstream/'.$bitstream->getKey().'/'.urlencode($bitstream->getName()).'">';
224224
echo $this->slicename($bitstream->getName(), 50);
225225
echo '</a>';
226226
if($this->isModerator)

0 commit comments

Comments
 (0)