HTTP のレスポンスヘッダーには Content-Disposition というフィールドがあり、クライアントにファイル保存時のファイル名を指定できる。
curl と wget で、このフィールドを参照してファイル保存する方法をメモ。
via http://superuser.com/questions/301044/how-to-wget-a-file-with-correct-name-when-redirected
実験するダウンロード用 URL
深い理由はないけれども、 次の vim スクリプトをダウンロードしたい。
$ curl -I "http://www.vim.org/scripts/download_script.php?src_id=19574" HTTP/1.1 200 OK Server: Apache/2.2.15 (CentOS) Vary: Host Content-Disposition: attachment; filename=taglist_46.zip Cache-Control: max-age=172800 Expires: Mon, 25 Aug 2014 04:13:16 GMT Content-Type: application/octetstream Date: Sat, 23 Aug 2014 04:13:16 GMT X-Varnish: 644882401 Age: 0 Via: 1.1 varnish Connection: keep-alive
HEAD メソッドでリクエストすると、Content-Disposition: attachment; filename=taglist_46.zip というようにファイル名 taglist_46.zip で保存するように仕向けている。
curl
curl の -O, --remote-name オプションを使うと、URL を元に保存ファイル名が決定される。
URL から download_script.php?src_id=19574 のファイル名で保存される。
$ curl -J -O "http://www.vim.org/scripts/download_script.php?src_id=19574" -D -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0HTTP/1.1 200 OK
Server: Apache/2.2.15 (CentOS)
Vary: Host
Content-Disposition: attachment; filename=taglist_46.zip
Cache-Control: max-age=172800
Expires: Mon, 25 Aug 2014 04:10:31 GMT
Content-Type: application/octetstream
Content-Length: 51455
Date: Sat, 23 Aug 2014 04:10:31 GMT
X-Varnish: 644876743
Age: 0
Via: 1.1 varnish
Connection: keep-alive
100 51455 100 51455 0 0 49566 0 0:00:01 0:00:01 --:--:-- 49619
curl: Saved to filename 'taglist_46.zip'
Write output to a local file named like the remote file we get. (Only the file part of the remote file is used, the path is cut off.)
The remote file name to use for saving is extracted from the given URL, nothing else.
Consequentially, the file will be saved in the current working directory. If you want the file saved in a different directory, make sure you change current working directory before you invoke curl with the -O, –remote-name flag!
There is no URL decoding done on the file name. If it has %20 or other URL encoded parts of the name, they will end up as-is as file name.
You may use this option as many times as the number of URLs you have.
-J, --remote-header-name オプションを使うと Content-Disposition を参照してファイル保存してくれる。
$ curl -O -J "http://www.vim.org/scripts/download_script.php?src_id=19574"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 51455 100 51455 0 0 85086 0 --:--:-- --:--:-- --:--:-- 85190
curl: Saved to filename 'taglist_46.zip'
(HTTP) This option tells the -O, –remote-name option to use the server-specified Content-Disposition filename instead of extracting a filename from the URL.
There’s no attempt to decode %-sequences (yet) in the provided file name, so this option may provide you with rather unexpected file names.
注意点としては -J, --remote-header-name オプションは2010年2月リリースの 7.20.0 で導入されたので、CentOS 6 のような古いOSを使っていると、標準の curl では使えない。
wget
何も考えずに
$ wget "http://www.vim.org/scripts/download_script.php?src_id=19574"
とやると download_script.php?src_id=19574 のファイル名で保存される。
--content-disposition オプションを使うと Content-Disposition を参照してファイル保存してくれる。
If this is set to on, experimental (not fully-functional) support for “Content-Disposition” headers is enabled. This can currently result in extra round-trips to the server for a “HEAD” request, and is known to suffer from a few bugs, which is why it is not currently enabled by default.
This option is useful for some file-downloading CGI programs that use “Content-Disposition” headers to describe what the name of a downloaded file should be.
$ wget --content-disposition "http://www.vim.org/scripts/download_script.php?src_id=19574" --2014-08-23 13:27:40-- http://www.vim.org/scripts/download_script.php?src_id=19574 Resolving www.vim.org (www.vim.org)... 216.34.181.97 Connecting to www.vim.org (www.vim.org)|216.34.181.97|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 51455 (50K) [application/octetstream] Saving to: ‘taglist_46.zip’ 100%[========================================================================================================>] 51,455 333KB/s in 0.2s 2014-08-23 13:27:40 (333 KB/s) - ‘taglist_46.zip’ saved [51455/51455]
MEMO
Test Cases for HTTP Content-Disposition header field (RFC 6266) and the Encodings defined in RFCs 2047, 2231 and 5987
http://greenbytes.de/tech/tc2231/
というサイトがある。
このページを眺めていると、ライブラリーの Content-Disposition の処理がおかしいからといって袖をまくり上げ、コードに飛び込むのは危険だということがわかる。
Leave a Reply