1:- module(bitrix24_request, [
    2          post/4, get/3]).    3
    4:- autoload(library(option),
    5            [option/2]).    6:- use_module(library(http/http_client)).    7:- use_module(library(uri)).    8:- use_module(bitrix24_utils, [decode_response/2, remove_json/2]).    9
   10:- debug(request(post)).   11:- debug(request(get)).   12post(Url, Body, Response, Options) :-
   13    http_request(post, Url, Body, Response, Options).
   14
   15get(Url, Response, Options) :-
   16    http_request(get, Url, _, Response, Options).
   17
   18http_request(post, Url, Body, Response, Options) :-
   19    execute_request(post, Url, Body, Reply, StatusCode, Options),
   20    status_code(StatusCode, Reply, Response, Url).
   21http_request(get, Url, Body, Response, Options) :-
   22    execute_request(get, Url, Body, Reply, StatusCode, Options),
   23    status_code(StatusCode, Reply, Response, Url).
   24
   25execute_request(post, Url, Body, Reply, StatusCode, Options) :-
   26    request_options(Options, StatusCode, HttpOptions),
   27    catch(
   28        http_post(Url, Body, Reply, HttpOptions),
   29        Error,
   30        throw_request_error(post, Url, Error)
   31    ).
   32execute_request(get, Url, _Body, Reply, StatusCode, Options) :-
   33    request_options(Options, StatusCode, HttpOptions),
   34    catch(
   35        http_get(Url, Reply, HttpOptions),
   36        Error,
   37        throw_request_error(get, Url, Error)
   38    ).
   39
   40request_options(Options, _StatusCode, Options) :-
   41    option(status_code(_), Options),
   42    !.
   43request_options(Options, StatusCode, [status_code(StatusCode)|Options]).
   44
   45throw_request_error(Method, Url, Error) :-
   46    redact_url(Url, SafeUrl),
   47    debug(request(Method), '~q~n', [Error]),
   48    throw(error(bitrix24_http_request_failed(Method, SafeUrl, Error), _)).
   49
   50status_code(200, Reply, Response, _Url) :- !,
   51    decode_response(Reply, Result),
   52    remove_json(Result, Response).
   53
   54status_code(StatusCode, Reply, Response, Url) :-
   55    decode_response(Reply, Response),
   56    redact_url(Url, SafeUrl),
   57    debug(http(error), 'error status code ~q : response ~q : reply ~q url: ~q', [StatusCode, Response, Reply, SafeUrl]).
   58
   59redact_url(Url, SafeUrl) :-
   60    uri_components(Url, Components),
   61    uri_data(search, Components, Search),
   62    nonvar(Search),
   63    Search \== '',
   64    !,
   65    uri_query_components(Search, QueryComponents),
   66    maplist(redact_query_component, QueryComponents, SafeComponents),
   67    uri_query_components(SafeSearch, SafeComponents),
   68    uri_data(search, Components, SafeSearch, SafeComponentsRecord),
   69    uri_components(SafeUrl, SafeComponentsRecord).
   70redact_url(Url, Url).
   71
   72redact_query_component(Name=_, Name='[REDACTED]') :-
   73    secret_query_key(Name),
   74    !.
   75redact_query_component(Component, Component).
   76
   77secret_query_key(auth).
   78secret_query_key(client_secret).
   79secret_query_key(refresh_token).
   80secret_query_key(access_token)