When using drush make, it is sometimes desirable to use a link to the 'latest version' of a third-party library. In the case of Sourceforge, a double redirect is employed, first to the latest version of the software and then a second redirect to the nearest mirror location. Without the ability to follow redirects, it is necessary to give drush make a link to a specific version and mirror location, which defeats the ability of Sourceforge to distribute load.
As an example I try to download the getID3 library from Sourceforge using the following make file.
core = 7.x
api = 2
; Libraries
; Latest stable getID3 library
libraries[getid3][download][type] = "get"
libraries[getid3][download][url] = "http://sourceforge.net/projects/getid3/files/latest/download?source=files"
libraries[getid3][directory_name] = "getid3"
libraries[getid3][overwrite] = TRUE
The output from drush --debug follows:
/opt/drush/drush make --debug --no-core getid3.make.inc /tmp/testing
Bootstrap to phase 0. [0.03 sec, 2.2 MB] [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drush() [0.03 sec, 2.34 MB] [bootstrap]
Cache HIT cid: 5.0-dev-commandfiles-0-d855919b3fd468a8cb48278c0b0162e2 [0.06 sec, 2.35 MB] [debug]
Bootstrap to phase 0. [0.14 sec, 5.16 MB] [bootstrap]
Bootstrap to phase 0. [0.17 sec, 5.16 MB] [bootstrap]
Found command: make (commandfile=make) [0.17 sec, 5.16 MB] [bootstrap]
Loading release_info engine. [0.21 sec, 5.18 MB] [notice]
Executing: which wget
/usr/bin/wget
Executing: wget -q --timeout=30 -O /tmp/download_fileeOAW5D 'http://sourceforge.net/projects/getid3/files/latest/download?source=files'
Calling is_readable(/tmp/download_fileeOAW5D) [2.96 sec, 5.32 MB] [debug]
Calling is_writable(/tmp/make_tmp_1330015110_4f466b865c60b) [2.96 sec, 5.32 MB] [debug]
Calling rename(/tmp/download_fileeOAW5D, /tmp/make_tmp_1330015110_4f466b865c60b/download) [2.96 sec, 5.32 MB] [debug]
getid3 downloaded from http://sourceforge.net/projects/getid3/files/latest/download?source=files. [2.96 sec, 5.32 MB] [ok]
Executing: mv /tmp/make_tmp_1330015110_4f466b865c60b/download /tmp/make_tmp_1330015110_4f466b865c60b/__build__/sites/all/libraries/getid3
Executing: mv /tmp/make_tmp_1330015110_4f466b865c60b/__build__ /tmp/make_tmp_1330015110_4f466b865c60b/testing
Executing: cp -Rf /tmp/make_tmp_1330015110_4f466b865c60b/testing /tmp
Executing: rm -rf /tmp/make_tmp_1330015110_4f466b865c60b
Command dispatch complete [3.09 sec, 5.29 MB] [notice]
Peak memory usage was 6.1 MB [3.09 sec, 5.29 MB] [memory]
# ls -l /tmp/testing/sites/all/libraries/getid3/
total 480K
drwxr-xr-x 2 root root 4.0K Feb 23 10:38 .
drwxr-xr-x 3 root root 4.0K Feb 23 10:38 ..
-rw------- 1 root root 470K Feb 23 10:38 download
As you can see, the getID3 library was actually downloaded, but since the filename was taken from the basename of the original URL, the type of file (.zip) was lost and so it was never unpacked.
The drush environment was:
# drush status
PHP configuration : /etc/php5/cli/php.ini
Drush version : 5.0-dev
Drush configuration :
Drush alias files : /etc/drush/publisher.alias.drushrc.php /etc/drush/developer.alias.drushrc.php /etc/drush/drupal7.alias.drushrc.php
A simple routine to get the filename and final URL from the headers when provided and default to the current behavior otherwise looks like this:
/**
* drush_get_file_redirect()
* Gets filename and final redirect from the headers for the given URL.
*
* @param string $url
* @return array ($filename, $url)
*/
function drush_get_file_redirect($url){
$headers = get_headers($url, 1);
if(!$headers) return false; //can't get headers
if(array_key_exists('Content-Disposition', $headers)){
preg_match('/^.*filename="(.*)"$/m', $headers['Content-Disposition'], $match);
$filename = $match[1];
}
if(array_key_exists('Location', $headers)){
$url = array_pop($headers['Location']);
}
if(!isset($filename)) $filename = basename($url);
if($filename != basename($url)) return false; //filename url mis-matched
return array($filename, $url);
}
I'll attach a patch and the --debug results in the next comment.
| Comment | File | Size | Author |
|---|---|---|---|
| #1 | drush-follow-redirects-1452338-#1.patch | 2.32 KB | dude4linux |
Comments
Comment #1
dude4linux commentedWith the attached patch installed, the --debug output is as follows:
The attached patch changes two places where the filename is determined by using basename on the original URL. A complete solution would need to find all cases where the original URL is used. The best solution would be to call 'drush_get_file_redirect' and store both the URL and filename in the download array.
Comment #2
dude4linux commentedOpps. Patch #1 has a typo. Working on a fix.
Comment #3
steven jones commentedThis should be fixed by #1447558: Make fails for library archives with no file "extension", please re-open this issue if its not.
Comment #4
dude4linux commentedWell, it wasn't fixed for me. I checked and the code from #1447558 is present in the version I tested above which still failed to unpack the zip file. I'm running:
which is failing unit tests and hangs when testing git.make
Comment #5
dude4linux commentedDarn, your right. It is working now. I must have refreshed after running the last test before preparing my revised patch and didn't think to re-run the test. The unit tests are still hanging for me, but that might be a local config problem.
Comment #6
steven jones commented