diff --git a/apps/efka/src/efka_downloader.erl b/apps/efka/src/efka_downloader.erl index 8c732cb..7708a09 100644 --- a/apps/efka/src/efka_downloader.erl +++ b/apps/efka/src/efka_downloader.erl @@ -28,7 +28,7 @@ %%%=================================================================== test() -> - {ok, Pid} = start_link("https://codeload.github.com/genadyo/LivePhotoDemo/zip/refs/heads/master", "/tmp/test.tar"), + {ok, Pid} = start_link("https://codeload.github.com/genadyo/LivePhotoDemo/zip/refs/heads/master", "/tmp/master.tar"), Ref = download(Pid), receive {download_response, Ref, Info} -> @@ -81,10 +81,14 @@ handle_call(_Request, _From, State = #state{}) -> {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). handle_cast({download, ReceiverPid, Ref}, State = #state{url = Url, target_file = TargetFile}) -> - case hackney:get(Url, [], <<>>, [async]) of + SSLOpts = {ssl_options, [ + % 完全禁用证书验证 + {verify, verify_none} + ]}, + + case hackney:request(get, Url, [], <<>>, [async, {pool, false}, SSLOpts]) of {ok, ClientRef} -> - {ok, File} = file:open(TargetFile, [write, binary]), - case receive_data(ClientRef, File) of + case receive_data(ClientRef, TargetFile) of ok -> ReceiverPid ! {download_response, Ref, ok}; {error, Reason} -> @@ -126,23 +130,57 @@ code_change(_OldVsn, State = #state{}, _Extra) -> %%% Internal functions %%%=================================================================== -receive_data(ClientRef, File) -> +receive_data(ClientRef, DefaultFile) -> receive - {hackney_response, ClientRef, {headers, _Headers}} -> - receive_data(ClientRef, File); {hackney_response, ClientRef, {status, 200, _Reason}} -> - receive_data(ClientRef, File); + lager:debug("22"), + receive_data0(ClientRef, DefaultFile); {hackney_response, ClientRef, {status, StatusCode, _Reason}} -> - lager:debug("call me here"), - {error, {http_status, StatusCode}}; - {hackney_response, ClientRef, Data} -> - file:write(File, Data), - receive_data(ClientRef, File); + {error, {http_status, StatusCode}} + end. +receive_data0(ClientRef, DefaultFile) -> + receive + {hackney_response, ClientRef, {headers, Headers}} -> + lager:debug("11 data bytes: ~p", [extra_filename(Headers)]), + TargetFile = case extra_filename(Headers) of + error -> + DefaultFile; + {ok, Filename} -> + Filename + end, + {ok, File} = file:open(TargetFile, [write, binary]), + receive_data1(ClientRef, File) + end. +receive_data1(ClientRef, File) -> + receive + {hackney_response, ClientRef, {error, Reason}} -> + lager:debug("error11"), + ok = file:close(File), + {error, Reason}; {hackney_response, ClientRef, done} -> + lager:debug("error22"), ok = file:close(File), hackney:close(ClientRef), ok; - {hackney_response, ClientRef, {error, Reason}} -> - ok = file:close(File), - {error, Reason} - end. \ No newline at end of file + {hackney_response, ClientRef, Data} -> + lager:debug("data: ~p", [byte_size(Data)]), + file:write(File, Data), + receive_data1(ClientRef, File) + end. + +-spec extra_filename(Headers :: list()) -> error | {ok, Filename :: string()}. +extra_filename(Headers) when is_list(Headers) -> + case lists:filter(fun({K, _}) -> string:lowercase(K) =:= <<"content-disposition">> end, Headers) of + [{_, <<"attachment; ", Rest/binary>>}|_] -> + Params0 = binary:split(Rest, <<";">>, [global]), + Params = lists:map(fun(P) -> list_to_tuple(binary:split(P, <<"=">>)) end, Params0), + filename(Params); + _ -> + error + end. +filename([]) -> + error; +filename([{<<"filename">>, Filename}|_]) -> + {ok, binary_to_list(Filename)}; +filename([_|Tail]) -> + filename(Tail). \ No newline at end of file