[curl/wget]Content-Dispositionのファイル名でダウンロードする

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 の処理がおかしいからといって袖をまくり上げ、コードに飛び込むのは危険だということがわかる。

Tagged with: , , , ,
Posted in linux

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 6 days ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 3 weeks ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 3 weeks ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 6 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 9 months ago
%d bloggers like this: