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

Commit 30d8303

Browse files
committed
ENH: refs #975. Support path-style download URLs
1 parent bc420ab commit 30d8303

File tree

4 files changed

+94
-10
lines changed

4 files changed

+94
-10
lines changed

core/controllers/DownloadController.php

Lines changed: 38 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
@@ -316,6 +314,40 @@ public function checksizeAction()
316314
}
317315
}
318316

317+
/**
318+
* This action exposes downloading a single item and should be called as
319+
* download/item/<item_id>/...
320+
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
321+
* if the content-disposition header is ignored by the user agent.
322+
*/
323+
public function itemAction()
324+
{
325+
$pathParams = UtilityComponent::extractPathParams();
326+
if(empty($pathParams))
327+
{
328+
throw new Zend_Exception('Must specify item id as a path parameter');
329+
}
330+
331+
$this->_forward('index', null, null, array('items' => $pathParams[0]));
332+
}
333+
334+
/**
335+
* This action exposes downloading a single folder and should be called as
336+
* download/folder/<folder_id>/...
337+
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
338+
* if the content-disposition header is ignored by the user agent.
339+
*/
340+
public function folderAction()
341+
{
342+
$pathParams = UtilityComponent::extractPathParams();
343+
if(empty($pathParams))
344+
{
345+
throw new Zend_Exception('Must specify folder id as a path parameter');
346+
}
347+
348+
$this->_forward('index', null, null, array('folders' => $pathParams[0]));
349+
}
350+
319351
/**
320352
* Render the view for the large data downloader applet
321353
* @param itemIds Comma separated list of items to download
@@ -445,7 +477,7 @@ private function _downloadEmptyItem($item)
445477
}
446478
ob_start();
447479
Zend_Loader::loadClass('ZipStream', BASE_PATH.'/library/ZipStream/');
448-
$this->_helper->viewRenderer->setNoRender();
480+
$this->disableView();
449481
if(isset($item) && $item instanceof ItemDao)
450482
{
451483
$name = $item->getName();

core/controllers/ShareController.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,25 @@ 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+
$name = $dao->getName();
365+
break;
366+
default:
367+
throw new Zend_Exception('Invalid type', 400);
368+
}
369+
370+
$baseUrl = $this->getRequest()->getScheme().'://'.$this->getRequest()->getHttpHost().$this->view->webroot;
358371
$this->view->type = $type;
359372
$this->view->id = $id;
360373
$this->view->viewUrl = $baseUrl.'/'.$type.'/'.$id;
361-
$this->view->downloadUrl = $baseUrl.'/download?'.$type.'s='.$id;
374+
$this->view->downloadUrl = $baseUrl.'/download/'.$type.'/'.$id.'/'.urlencode($name);
362375
}
363376
}//end class
364377

core/controllers/components/UtilityComponent.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,37 @@ 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+
for( ; $i < count($allTokens); $i++)
121+
{
122+
$tokens[] = $allTokens[$i];
123+
}
124+
return $tokens;
125+
}
126+
96127
/** find modules configuration in a folder */
97128
private function _initModulesConfig($dir)
98129
{

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);

0 commit comments

Comments
 (0)