diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/rebar_pkg_resource.erl | 36 | 
1 files changed, 26 insertions, 10 deletions
| diff --git a/src/rebar_pkg_resource.erl b/src/rebar_pkg_resource.erl index 7d42ccd..2fb1868 100644 --- a/src/rebar_pkg_resource.erl +++ b/src/rebar_pkg_resource.erl @@ -6,6 +6,7 @@  -export([lock/2          ,download/3 +        ,download/4          ,needs_update/2          ,make_vsn/1]). @@ -13,6 +14,8 @@          ,etag/1          ,ssl_opts/1]). +-export([store_etag_in_cache/2]). +  -include("rebar.hrl").  -include_lib("public_key/include/OTP-PUB-KEY.hrl"). @@ -28,27 +31,34 @@ needs_update(Dir, {pkg, _Name, Vsn, _Hash}) ->              true      end. -download(TmpDir, Pkg={pkg, Name, Vsn, _Hash}, State) -> +download(TmpDir, Pkg, State) -> +    download(TmpDir, Pkg, State, true). + +download(TmpDir, Pkg={pkg, Name, Vsn, _Hash}, State, UpdateETag) ->      CDN = rebar_state:get(State, rebar_packages_cdn, ?DEFAULT_CDN),      {ok, PackageDir} = rebar_packages:package_dir(State),      Package = binary_to_list(<<Name/binary, "-", Vsn/binary, ".tar">>), +    ETagFile = binary_to_list(<<Name/binary, "-", Vsn/binary, ".etag">>),      CachePath = filename:join(PackageDir, Package), +    ETagPath = filename:join(PackageDir, ETagFile),      case rebar_utils:url_append_path(CDN, filename:join(?REMOTE_PACKAGE_DIR, Package)) of          {ok, Url} -> -            cached_download(TmpDir, CachePath, Pkg, Url, etag(CachePath), State); +            cached_download(TmpDir, CachePath, Pkg, Url, etag(ETagPath), State, ETagPath, UpdateETag);          _ ->              {fetch_fail, Name, Vsn}      end. -cached_download(TmpDir, CachePath, Pkg={pkg, Name, Vsn, _Hash}, Url, ETag, State) -> +cached_download(TmpDir, CachePath, Pkg={pkg, Name, Vsn, _Hash}, Url, ETag, State, ETagPath, UpdateETag) ->      case request(Url, ETag) of          {ok, cached} ->              ?INFO("Version cached at ~ts is up to date, reusing it", [CachePath]),              serve_from_cache(TmpDir, CachePath, Pkg, State);          {ok, Body, NewETag} ->              ?INFO("Downloaded package, caching at ~ts", [CachePath]), -            serve_from_download(TmpDir, CachePath, Pkg, NewETag, Body, State); +            maybe_store_etag_in_cache(UpdateETag, ETagPath, NewETag), +            serve_from_download(TmpDir, CachePath, Pkg, NewETag, Body, State, ETagPath);          error when ETag =/= false -> +            store_etag_in_cache(ETagPath, ETag),              ?INFO("Download error, using cached file at ~ts", [CachePath]),              serve_from_cache(TmpDir, CachePath, Pkg, State);          error -> @@ -75,10 +85,10 @@ serve_from_cache(TmpDir, CachePath, Pkg, State) ->              {bad_checksum, CachePath}      end. -serve_from_download(TmpDir, CachePath, Package, ETag, Binary, State) -> +serve_from_download(TmpDir, CachePath, Package, ETag, Binary, State, ETagPath) ->      ?DEBUG("Writing ~p to cache at ~ts", [Package, CachePath]),      file:write_file(CachePath, Binary), -    case etag(CachePath) of +    case etag(ETagPath) of          ETag ->              serve_from_cache(TmpDir, CachePath, Package, State);          FileETag -> @@ -86,7 +96,6 @@ serve_from_download(TmpDir, CachePath, Package, ETag, Binary, State) ->              {bad_download, CachePath}      end. -  extract(TmpDir, CachePath) ->      ec_file:mkdir_p(TmpDir),      {ok, Files} = erl_tar:extract(CachePath, [memory]), @@ -131,9 +140,8 @@ request(Url, ETag) ->  etag(Path) ->      case file:read_file(Path) of -        {ok, Binary} -> -            <<X:128/big-unsigned-integer>> = crypto:hash(md5, Binary), -            rebar_string:lowercase(lists:flatten(io_lib:format("~32.16.0b", [X]))); +        {ok, Bin} -> +            binary_to_list(Bin);          {error, _} ->              false      end. @@ -216,3 +224,11 @@ version_pad([Major, Minor, Patch]) ->      {list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)};  version_pad([Major, Minor, Patch | _]) ->      {list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)}. + +maybe_store_etag_in_cache(false = _UpdateETag, _Path, _ETag) -> +    ok; +maybe_store_etag_in_cache(true = _UpdateETag, Path, ETag) -> +    store_etag_in_cache(Path, ETag). + +store_etag_in_cache(Path, ETag) -> +    _ = file:write_file(Path, ETag). | 
