LoginSignup
1
0

More than 5 years have passed since last update.

ETagヘッダにハッシュ値が付加されるリソースとの同一性確認には If-None-Match を使う。

Posted at

はじめに

 以前、Amazon S3に何かをコピーするときに、すでに同じものをコピー済みかどうかをチェックするシェル関数 という記事を上げましたが、リファクタして以下に行きつきました。

If-None-Match を使えばスッキリ

 ETagでリソースのハッシュを返してくれるWEBサーバーならば、リクエストに比較対象のハッシュ値を指定したIf-None-Matchヘッダを付加すると、WEBサーバー側にあるリソースのハッシュと同じであれば、304 Not Modifiedを返してくれる(はず)。これを使います。

#!/bin/bash
#
# get_status_If_None_Match
# 
# パラメータ:
#                                                                                                                                                                               
# $1: サーバーにあるものと同一かどうかを判定するファイルのパス
#     (例: /var/contents/sports/baseball/20160807-001.mov)
#
# $2: 上記のファイルがサーバーに上がっている場合のURL
#      (例: http://hoge-journal.s3.amazonaws.com/sports/baseball/20160807-001.mov)
#
function get_status_If_None_Match() {

    curl -s -I -o /dev/null $2 \
        --header "If-None-Match: \"`openssl md5 $1 | awk '{print $2}'`\"" \
        -w '%{http_code}'

}

 この関数は、$1$2の状態をWEBサーバが適切に判断して、レスポンスのステータスコードに反映することを前提に、以下の値を出力することを想定しています。

$1と$2の状態
$2が示すリソースは$1で指定したファイルと同一 304
$2が示すリソースは$1で指定したファイルと異なる。 200
$2で指定したリソースは存在しない。(ので使用不可) 404(403)

使用例

元記事の例にこの関数を使うとすると


if [ $((`get_status_If_None_Match ${FILE_PATH} ${S3_URL}`)) -ne 304 ]; then
  aws s3 cp ${FILE_PATH} ${S3_BUCKET_PATH} --acl public-read
fi

とすればよい。

参考

追記

以下の部分は、さらにコードを短くできる。

openssl md5 $1 | awk '{print $2}'

上記は、md5コマンドが使えるのなら、これを-q(quiet)オプションとともに使って、

md5 -q $1

で代替可能

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0