summaryrefslogtreecommitdiff
path: root/src/couch_replicator/src/couch_replicator_ids.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch_replicator/src/couch_replicator_ids.erl')
-rw-r--r--src/couch_replicator/src/couch_replicator_ids.erl297
1 files changed, 150 insertions, 147 deletions
diff --git a/src/couch_replicator/src/couch_replicator_ids.erl b/src/couch_replicator/src/couch_replicator_ids.erl
index 316e6a28a..6543cf069 100644
--- a/src/couch_replicator/src/couch_replicator_ids.erl
+++ b/src/couch_replicator/src/couch_replicator_ids.erl
@@ -34,7 +34,6 @@ replication_id(#rep{options = Options} = Rep) ->
BaseId = replication_id(Rep, ?REP_ID_VERSION),
{BaseId, maybe_append_options([continuous, create_target], Options)}.
-
% Versioned clauses for generating replication IDs.
% If a change is made to how replications are identified,
% please add a new clause and increase ?REP_ID_VERSION.
@@ -44,37 +43,34 @@ replication_id(#rep{} = Rep, 4) ->
SrcInfo = get_v4_endpoint(Rep#rep.source),
TgtInfo = get_v4_endpoint(Rep#rep.target),
maybe_append_filters([UUID, SrcInfo, TgtInfo], Rep);
-
replication_id(#rep{} = Rep, 3) ->
UUID = couch_server:get_uuid(),
Src = get_rep_endpoint(Rep#rep.source),
Tgt = get_rep_endpoint(Rep#rep.target),
maybe_append_filters([UUID, Src, Tgt], Rep);
-
replication_id(#rep{} = Rep, 2) ->
{ok, HostName} = inet:gethostname(),
- Port = case (catch mochiweb_socket_server:get(couch_httpd, port)) of
- P when is_number(P) ->
- P;
- _ ->
- % On restart we might be called before the couch_httpd process is
- % started.
- % TODO: we might be under an SSL socket server only, or both under
- % SSL and a non-SSL socket.
- % ... mochiweb_socket_server:get(https, port)
- config:get_integer("httpd", "port", 5984)
- end,
+ Port =
+ case (catch mochiweb_socket_server:get(couch_httpd, port)) of
+ P when is_number(P) ->
+ P;
+ _ ->
+ % On restart we might be called before the couch_httpd process is
+ % started.
+ % TODO: we might be under an SSL socket server only, or both under
+ % SSL and a non-SSL socket.
+ % ... mochiweb_socket_server:get(https, port)
+ config:get_integer("httpd", "port", 5984)
+ end,
Src = get_rep_endpoint(Rep#rep.source),
Tgt = get_rep_endpoint(Rep#rep.target),
maybe_append_filters([HostName, Port, Src, Tgt], Rep);
-
replication_id(#rep{} = Rep, 1) ->
{ok, HostName} = inet:gethostname(),
Src = get_rep_endpoint(Rep#rep.source),
Tgt = get_rep_endpoint(Rep#rep.target),
maybe_append_filters([HostName, Src, Tgt], Rep).
-
-spec convert([_] | binary() | {string(), string()}) -> {string(), string()}.
convert(Id) when is_list(Id) ->
convert(?l2b(Id));
@@ -87,59 +83,62 @@ convert(Id0) when is_binary(Id0) ->
convert({BaseId, Ext} = Id) when is_list(BaseId), is_list(Ext) ->
Id.
-
% Private functions
-maybe_append_filters(Base,
- #rep{source = Source, options = Options}) ->
- Base2 = Base ++
- case couch_replicator_filters:parse(Options) of
- {ok, nil} ->
- [];
- {ok, {view, Filter, QueryParams}} ->
- [Filter, QueryParams];
- {ok, {user, {Doc, Filter}, QueryParams}} ->
- case couch_replicator_filters:fetch(Doc, Filter, Source) of
- {ok, Code} ->
- [Code, QueryParams];
- {error, Error} ->
- throw({filter_fetch_error, Error})
- end;
- {ok, {docids, DocIds}} ->
- [DocIds];
- {ok, {mango, Selector}} ->
- [Selector];
- {error, FilterParseError} ->
- throw({error, FilterParseError})
- end,
+maybe_append_filters(
+ Base,
+ #rep{source = Source, options = Options}
+) ->
+ Base2 =
+ Base ++
+ case couch_replicator_filters:parse(Options) of
+ {ok, nil} ->
+ [];
+ {ok, {view, Filter, QueryParams}} ->
+ [Filter, QueryParams];
+ {ok, {user, {Doc, Filter}, QueryParams}} ->
+ case couch_replicator_filters:fetch(Doc, Filter, Source) of
+ {ok, Code} ->
+ [Code, QueryParams];
+ {error, Error} ->
+ throw({filter_fetch_error, Error})
+ end;
+ {ok, {docids, DocIds}} ->
+ [DocIds];
+ {ok, {mango, Selector}} ->
+ [Selector];
+ {error, FilterParseError} ->
+ throw({error, FilterParseError})
+ end,
couch_util:to_hex(couch_hash:md5_hash(term_to_binary(Base2))).
-
maybe_append_options(Options, RepOptions) ->
- lists:foldl(fun(Option, Acc) ->
- Acc ++
- case couch_util:get_value(Option, RepOptions, false) of
- true ->
- "+" ++ atom_to_list(Option);
- false ->
- ""
- end
- end, [], Options).
-
+ lists:foldl(
+ fun(Option, Acc) ->
+ Acc ++
+ case couch_util:get_value(Option, RepOptions, false) of
+ true ->
+ "+" ++ atom_to_list(Option);
+ false ->
+ ""
+ end
+ end,
+ [],
+ Options
+ ).
-get_rep_endpoint(#httpdb{url=Url, headers=Headers}) ->
+get_rep_endpoint(#httpdb{url = Url, headers = Headers}) ->
DefaultHeaders = (#httpdb{})#httpdb.headers,
{remote, Url, Headers -- DefaultHeaders}.
-
get_v4_endpoint(#httpdb{} = HttpDb) ->
{remote, Url, Headers} = get_rep_endpoint(HttpDb),
{User, _} = couch_replicator_utils:get_basic_auth_creds(HttpDb),
{Host, NonDefaultPort, Path} = get_v4_url_info(Url),
- OAuth = undefined, % Keep this to ensure checkpoints don't change
+ % Keep this to ensure checkpoints don't change
+ OAuth = undefined,
{remote, User, Host, NonDefaultPort, Path, Headers, OAuth}.
-
get_v4_url_info(Url) when is_binary(Url) ->
get_v4_url_info(binary_to_list(Url));
get_v4_url_info(Url) ->
@@ -158,7 +157,6 @@ get_v4_url_info(Url) ->
{Host, NonDefaultPort, Path}
end.
-
get_non_default_port(https, 443) ->
default;
get_non_default_port(http, 80) ->
@@ -168,112 +166,117 @@ get_non_default_port(http, 5984) ->
get_non_default_port(_Schema, Port) ->
Port.
-
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-
replication_id_convert_test_() ->
- [?_assertEqual(Expected, convert(Id)) || {Expected, Id} <- [
- {{"abc", ""}, "abc"},
- {{"abc", ""}, <<"abc">>},
- {{"abc", "+x+y"}, <<"abc+x+y">>},
- {{"abc", "+x+y"}, {"abc", "+x+y"}},
- {{"abc", "+x+y"}, <<"abc x y">>}
- ]].
+ [
+ ?_assertEqual(Expected, convert(Id))
+ || {Expected, Id} <- [
+ {{"abc", ""}, "abc"},
+ {{"abc", ""}, <<"abc">>},
+ {{"abc", "+x+y"}, <<"abc+x+y">>},
+ {{"abc", "+x+y"}, {"abc", "+x+y"}},
+ {{"abc", "+x+y"}, <<"abc x y">>}
+ ]
+ ].
http_v4_endpoint_test_() ->
- [?_assertMatch({remote, User, Host, Port, Path, HeadersNoAuth, undefined},
- begin
- HttpDb = #httpdb{url = Url, headers = Headers, auth_props = Auth},
- HttpDb1 = couch_replicator_utils:normalize_basic_auth(HttpDb),
- get_v4_endpoint(HttpDb1)
- end) ||
- {{User, Host, Port, Path, HeadersNoAuth}, {Url, Headers, Auth}} <- [
- {
- {undefined, "host", default, "/", []},
- {"http://host", [], []}
- },
- {
- {undefined, "host", default, "/", []},
- {"https://host", [], []}
- },
- {
- {undefined, "host", default, "/", []},
- {"http://host:5984", [], []}
- },
- {
- {undefined, "host", 1, "/", []},
- {"http://host:1", [], []}
- },
- {
- {undefined, "host", 2, "/", []},
- {"https://host:2", [], []}
- },
- {
- {undefined, "host", default, "/", [{"h","v"}]},
- {"http://host", [{"h","v"}], []}
- },
- {
- {undefined, "host", default, "/a/b", []},
- {"http://host/a/b", [], []}
- },
- {
- {"user", "host", default, "/", []},
- {"http://user:pass@host", [], []}
- },
- {
- {"user", "host", 3, "/", []},
- {"http://user:pass@host:3", [], []}
- },
- {
- {"user", "host", default, "/", []},
- {"http://user:newpass@host", [], []}
- },
- {
- {"user", "host", default, "/", []},
- {"http://host", [basic_auth("user","pass")], []}
- },
- {
- {"user", "host", default, "/", []},
- {"http://host", [basic_auth("user","newpass")], []}
- },
- {
- {"user3", "host", default, "/", []},
- {"http://user1:pass1@host", [basic_auth("user2","pass2")],
- auth_props("user3", "pass3")}
- },
- {
- {"user2", "host", default, "/", [{"h", "v"}]},
- {"http://host", [{"h", "v"}, basic_auth("user","pass")],
- auth_props("user2", "pass2")}
- },
- {
- {"user", "host", default, "/", [{"h", "v"}]},
- {"http://host", [{"h", "v"}], auth_props("user", "pass")}
- },
- {
- {undefined, "random_junk", undefined, undefined},
- {"random_junk", [], []}
- },
- {
- {undefined, "host", default, "/", []},
- {"http://host", [{"Authorization", "Basic bad"}], []}
- }
+ [
+ ?_assertMatch(
+ {remote, User, Host, Port, Path, HeadersNoAuth, undefined},
+ begin
+ HttpDb = #httpdb{url = Url, headers = Headers, auth_props = Auth},
+ HttpDb1 = couch_replicator_utils:normalize_basic_auth(HttpDb),
+ get_v4_endpoint(HttpDb1)
+ end
+ )
+ || {{User, Host, Port, Path, HeadersNoAuth}, {Url, Headers, Auth}} <- [
+ {
+ {undefined, "host", default, "/", []},
+ {"http://host", [], []}
+ },
+ {
+ {undefined, "host", default, "/", []},
+ {"https://host", [], []}
+ },
+ {
+ {undefined, "host", default, "/", []},
+ {"http://host:5984", [], []}
+ },
+ {
+ {undefined, "host", 1, "/", []},
+ {"http://host:1", [], []}
+ },
+ {
+ {undefined, "host", 2, "/", []},
+ {"https://host:2", [], []}
+ },
+ {
+ {undefined, "host", default, "/", [{"h", "v"}]},
+ {"http://host", [{"h", "v"}], []}
+ },
+ {
+ {undefined, "host", default, "/a/b", []},
+ {"http://host/a/b", [], []}
+ },
+ {
+ {"user", "host", default, "/", []},
+ {"http://user:pass@host", [], []}
+ },
+ {
+ {"user", "host", 3, "/", []},
+ {"http://user:pass@host:3", [], []}
+ },
+ {
+ {"user", "host", default, "/", []},
+ {"http://user:newpass@host", [], []}
+ },
+ {
+ {"user", "host", default, "/", []},
+ {"http://host", [basic_auth("user", "pass")], []}
+ },
+ {
+ {"user", "host", default, "/", []},
+ {"http://host", [basic_auth("user", "newpass")], []}
+ },
+ {
+ {"user3", "host", default, "/", []},
+ {"http://user1:pass1@host", [basic_auth("user2", "pass2")],
+ auth_props("user3", "pass3")}
+ },
+ {
+ {"user2", "host", default, "/", [{"h", "v"}]},
+ {"http://host", [{"h", "v"}, basic_auth("user", "pass")],
+ auth_props("user2", "pass2")}
+ },
+ {
+ {"user", "host", default, "/", [{"h", "v"}]},
+ {"http://host", [{"h", "v"}], auth_props("user", "pass")}
+ },
+ {
+ {undefined, "random_junk", undefined, undefined},
+ {"random_junk", [], []}
+ },
+ {
+ {undefined, "host", default, "/", []},
+ {"http://host", [{"Authorization", "Basic bad"}], []}
+ }
]
].
-
basic_auth(User, Pass) ->
B64Auth = base64:encode_to_string(User ++ ":" ++ Pass),
{"Authorization", "Basic " ++ B64Auth}.
-
auth_props(User, Pass) when is_list(User), is_list(Pass) ->
- [{<<"basic">>, {[
- {<<"username">>, list_to_binary(User)},
- {<<"password">>, list_to_binary(Pass)}
- ]}}].
+ [
+ {<<"basic">>,
+ {[
+ {<<"username">>, list_to_binary(User)},
+ {<<"password">>, list_to_binary(Pass)}
+ ]}}
+ ].
-endif.