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

Commit

Permalink
ENH: refs #975. Support path-style download URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
zachmullen committed Mar 8, 2013
1 parent bc420ab commit 30d8303
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 10 deletions.
44 changes: 38 additions & 6 deletions core/controllers/DownloadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public function indexAction()
$folderIds = $this->_getParam('folders');
$bitsreamid = $this->_getParam('bitstream');
$sessionUser = $this->userSession->Dao;
$testingMode = Zend_Registry::get('configGlobal')->environment == 'testing';
if($sessionUser != null)
{
// Make sure this is a copy and not a reference
Expand Down Expand Up @@ -148,7 +149,7 @@ public function indexAction()
$revision = $revisions[0];
$bitstreams = $revision->getBitstreams();

if($this->_getParam('testingmode') == '1')
if($testingMode)
{
$bitstreams = array($bitstreams[0]);
}
Expand All @@ -167,10 +168,7 @@ public function indexAction()
return;
}
$this->disableView();
if($this->_getParam('testingmode') == '1')
{
$this->Component->DownloadBitstream->testingmode = true;
}
$this->Component->DownloadBitstream->testingmode = $testingMode;
$this->Component->DownloadBitstream->download($bitstreams[0], $offset, true);
}
else
Expand Down Expand Up @@ -316,6 +314,40 @@ public function checksizeAction()
}
}

/**
* This action exposes downloading a single item and should be called as
* download/item/<item_id>/...
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
* if the content-disposition header is ignored by the user agent.
*/
public function itemAction()
{
$pathParams = UtilityComponent::extractPathParams();
if(empty($pathParams))
{
throw new Zend_Exception('Must specify item id as a path parameter');
}

$this->_forward('index', null, null, array('items' => $pathParams[0]));
}

/**
* This action exposes downloading a single folder and should be called as
* download/folder/<folder_id>/...
* Any extra parameters are ignored and can be used to force clients like wget to download to the correct filename
* if the content-disposition header is ignored by the user agent.
*/
public function folderAction()
{
$pathParams = UtilityComponent::extractPathParams();
if(empty($pathParams))
{
throw new Zend_Exception('Must specify folder id as a path parameter');
}

$this->_forward('index', null, null, array('folders' => $pathParams[0]));
}

/**
* Render the view for the large data downloader applet
* @param itemIds Comma separated list of items to download
Expand Down Expand Up @@ -445,7 +477,7 @@ private function _downloadEmptyItem($item)
}
ob_start();
Zend_Loader::loadClass('ZipStream', BASE_PATH.'/library/ZipStream/');
$this->_helper->viewRenderer->setNoRender();
$this->disableView();
if(isset($item) && $item instanceof ItemDao)
{
$name = $item->getName();
Expand Down
19 changes: 16 additions & 3 deletions core/controllers/ShareController.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,25 @@ function linksAction()
$type = $this->_getParam('type');
$id = $this->_getParam('id');

$request = Zend_Controller_Front::getInstance()->getRequest();
$baseUrl = $request->getScheme().'://'.$request->getHttpHost().$this->view->webroot;
switch($type)
{
case 'folder':
$dao = $this->Folder->load($id);
$name = $dao->getName().'.zip';
break;
case 'item':
$dao = $this->Item->load($id);
$name = $dao->getName();
break;
default:
throw new Zend_Exception('Invalid type', 400);
}

$baseUrl = $this->getRequest()->getScheme().'://'.$this->getRequest()->getHttpHost().$this->view->webroot;
$this->view->type = $type;
$this->view->id = $id;
$this->view->viewUrl = $baseUrl.'/'.$type.'/'.$id;
$this->view->downloadUrl = $baseUrl.'/download?'.$type.'s='.$id;
$this->view->downloadUrl = $baseUrl.'/download/'.$type.'/'.$id.'/'.urlencode($name);
}
}//end class

31 changes: 31 additions & 0 deletions core/controllers/components/UtilityComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,37 @@ public function getAllModules()
return $modules;
}

/**
* Helper method to extract tokens from request URI's in path form,
* e.g. download/folder/123/folder_name, starting after the action name.
* Returns the token as a list.
*/
public static function extractPathParams()
{
$request = Zend_Controller_Front::getInstance()->getRequest();
$allTokens = preg_split('@/@', $request->getPathInfo(), NULL, PREG_SPLIT_NO_EMPTY);

$tokens = array();
$i = 0;
if($request->getModuleName() != 'default')
{
$i++;
}
if($request->getControllerName() != 'index')
{
$i++;
}
if($request->getActionName() != 'index')
{
$i++;
}
for( ; $i < count($allTokens); $i++)
{
$tokens[] = $allTokens[$i];
}
return $tokens;
}

/** find modules configuration in a folder */
private function _initModulesConfig($dir)
{
Expand Down
10 changes: 9 additions & 1 deletion core/tests/controllers/UploadDownloadControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,15 @@ function testDownloadAction()

$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; //must be set in order to lock active download
$this->setupDatabase(array('activedownload')); //wipe any old locks
$this->dispatchUrI('/download?testingmode=1&items='.$itemId, $userDao);
$this->dispatchUrI('/download?items='.$itemId, $userDao);
$downloadedMd5 = md5($this->getBody());

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

// Test our special path-style URL endpoints for downloading single items or folders
$this->resetAll();
$this->setupDatabase(array('activedownload')); //wipe any old locks
$this->dispatchUrI('/download/item/'.$itemId.'/', $userDao);
$downloadedMd5 = md5($this->getBody());

$this->assertEquals($actualMd5, $downloadedMd5);
Expand Down

0 comments on commit 30d8303

Please sign in to comment.