diff options
Diffstat (limited to 'src/couch_replicator/src/couch_replicator_ids.erl')
-rw-r--r-- | src/couch_replicator/src/couch_replicator_ids.erl | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/src/couch_replicator/src/couch_replicator_ids.erl b/src/couch_replicator/src/couch_replicator_ids.erl deleted file mode 100644 index 04e71c3ef..000000000 --- a/src/couch_replicator/src/couch_replicator_ids.erl +++ /dev/null @@ -1,275 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(couch_replicator_ids). - --export([ - replication_id/1, - replication_id/2, - convert/1 -]). - --include_lib("ibrowse/include/ibrowse.hrl"). - --include_lib("couch/include/couch_db.hrl"). --include_lib("couch_replicator/include/couch_replicator_api_wrap.hrl"). --include("couch_replicator.hrl"). - -% replication_id/1 and replication_id/2 will attempt to fetch -% filter code for filtered replications. If fetching or parsing -% of the remotely fetched filter code fails they throw: -% {filter_fetch_error, Error} exception. -% - -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. - -replication_id(#rep{} = Rep, 4) -> - UUID = couch_server:get_uuid(), - 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) - list_to_integer(config:get("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)); -convert(Id0) when is_binary(Id0) -> - % Spaces can result from mochiweb incorrectly unquoting + characters from - % the URL path. So undo the incorrect parsing here to avoid forcing - % users to url encode + characters. - Id = binary:replace(Id0, <<" ">>, <<"+">>, [global]), - lists:splitwith(fun(Char) -> Char =/= $+ end, ?b2l(Id)); -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, - 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). - - -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), - {{UserFromHeaders, _}, HeadersWithoutBasicAuth} = - couch_replicator_utils:remove_basic_auth_from_headers(Headers), - {UserFromUrl, Host, NonDefaultPort, Path} = get_v4_url_info(Url), - User = pick_defined_value([UserFromUrl, UserFromHeaders]), - OAuth = undefined, % Keep this to ensure checkpoints don't change - {remote, User, Host, NonDefaultPort, Path, HeadersWithoutBasicAuth, OAuth}. - - -pick_defined_value(Values) -> - case [V || V <- Values, V /= undefined] of - [] -> - undefined; - DefinedValues -> - hd(DefinedValues) - end. - - -get_v4_url_info(Url) when is_binary(Url) -> - get_v4_url_info(binary_to_list(Url)); -get_v4_url_info(Url) -> - case ibrowse_lib:parse_url(Url) of - {error, invalid_uri} -> - % Tolerate errors here to avoid a bad user document - % crashing the replicator - {undefined, Url, undefined, undefined}; - #url{ - protocol = Schema, - username = User, - host = Host, - port = Port, - path = Path - } -> - NonDefaultPort = get_non_default_port(Schema, Port), - {User, Host, NonDefaultPort, Path} - end. - - -get_non_default_port(https, 443) -> - default; -get_non_default_port(http, 80) -> - default; -get_non_default_port(http, 5984) -> - default; -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">>} - ]]. - -http_v4_endpoint_test_() -> - [?_assertMatch({remote, User, Host, Port, Path, HeadersNoAuth, undefined}, - get_v4_endpoint(#httpdb{url = Url, headers = Headers})) || - {{User, Host, Port, Path, HeadersNoAuth}, {Url, Headers}} <- [ - { - {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")]} - }, - { - {"user1", "host", default, "/", []}, - {"http://user1:pass1@host", [basic_auth("user2","pass2")]} - }, - { - {"user", "host", default, "/", [{"h", "v"}]}, - {"http://host", [{"h", "v"}, basic_auth("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}. - - --endif. |