summaryrefslogtreecommitdiff
path: root/src/couch_replicator/src/couch_replicator_httpd.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch_replicator/src/couch_replicator_httpd.erl')
-rw-r--r--src/couch_replicator/src/couch_replicator_httpd.erl173
1 files changed, 0 insertions, 173 deletions
diff --git a/src/couch_replicator/src/couch_replicator_httpd.erl b/src/couch_replicator/src/couch_replicator_httpd.erl
deleted file mode 100644
index abd9f7fd0..000000000
--- a/src/couch_replicator/src/couch_replicator_httpd.erl
+++ /dev/null
@@ -1,173 +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_httpd).
-
--include_lib("couch/include/couch_db.hrl").
--include_lib("couch_mrview/include/couch_mrview.hrl").
-
--export([
- handle_req/1,
- handle_scheduler_req/1
-]).
-
--import(couch_httpd, [
- send_json/2,
- send_json/3,
- send_method_not_allowed/2
-]).
-
--import(couch_util, [
- to_binary/1
-]).
-
-
--define(DEFAULT_TASK_LIMIT, 100).
--define(REPDB, <<"_replicator">>).
-% This is a macro so it can be used as a guard
--define(ISREPDB(X), X =:= ?REPDB orelse binary_part(X, {byte_size(X), -12})
- =:= <<"/_replicator">>).
-
-
-handle_scheduler_req(#httpd{method='GET', path_parts=[_,<<"jobs">>]}=Req) ->
- Limit = couch_replicator_httpd_util:parse_int_param(Req, "limit",
- ?DEFAULT_TASK_LIMIT, 0, infinity),
- Skip = couch_replicator_httpd_util:parse_int_param(Req, "skip", 0, 0,
- infinity),
- {Replies, _BadNodes} = rpc:multicall(couch_replicator_scheduler, jobs, []),
- Flatlist = lists:concat(Replies),
- % couch_replicator_scheduler:job_ejson/1 guarantees {id, Id} to be the
- % the first item in the list
- Sorted = lists:sort(fun({[{id,A}|_]},{[{id,B}|_]}) -> A =< B end, Flatlist),
- Total = length(Sorted),
- Offset = min(Skip, Total),
- Sublist = lists:sublist(Sorted, Offset+1, Limit),
- Sublist1 = [couch_replicator_httpd_util:update_db_name(Task)
- || Task <- Sublist],
- send_json(Req, {[{total_rows, Total}, {offset, Offset}, {jobs, Sublist1}]});
-handle_scheduler_req(#httpd{method='GET', path_parts=[_,<<"jobs">>,JobId]}=Req) ->
- case couch_replicator:job(JobId) of
- {ok, JobInfo} ->
- send_json(Req, couch_replicator_httpd_util:update_db_name(JobInfo));
- {error, not_found} ->
- throw(not_found)
- end;
-handle_scheduler_req(#httpd{method='GET', path_parts=[_,<<"docs">>]}=Req) ->
- handle_scheduler_docs(?REPDB, Req);
-handle_scheduler_req(#httpd{method='GET', path_parts=[_,<<"docs">>,Db]}=Req)
- when ?ISREPDB(Db) ->
- handle_scheduler_docs(Db, Req);
-handle_scheduler_req(#httpd{method='GET', path_parts=[_,<<"docs">>,Db,DocId]}
- = Req) when ?ISREPDB(Db) ->
- handle_scheduler_doc(Db, DocId, Req);
-% Allow users to pass in unencoded _replicator database names (/ are not
-% escaped). This is possible here because _replicator is not a valid document
-% ID so can disambiguate between an element of a db path and the document ID.
-handle_scheduler_req(#httpd{method='GET', path_parts=[_,<<"docs">>|Unquoted]}
- = Req) ->
- case parse_unquoted_docs_path(Unquoted) of
- {db_only, Db} ->
- handle_scheduler_docs(Db, Req);
- {db_and_doc, Db, DocId} ->
- handle_scheduler_doc(Db, DocId, Req);
- {error, invalid} ->
- throw(bad_request)
- end;
-handle_scheduler_req(#httpd{method='GET'} = Req) ->
- send_json(Req, 404, {[{error, <<"not found">>}]});
-handle_scheduler_req(Req) ->
- send_method_not_allowed(Req, "GET,HEAD").
-
-
-handle_req(#httpd{method = 'POST', user_ctx = UserCtx} = Req) ->
- couch_httpd:validate_ctype(Req, "application/json"),
- RepDoc = {Props} = couch_httpd:json_body_obj(Req),
- couch_replicator_httpd_util:validate_rep_props(Props),
- case couch_replicator:replicate(RepDoc, UserCtx) of
- {error, {Error, Reason}} ->
- send_json(
- Req, 500,
- {[{error, to_binary(Error)}, {reason, to_binary(Reason)}]});
- {error, not_found} ->
- % Tried to cancel a replication that didn't exist.
- send_json(Req, 404, {[{error, <<"not found">>}]});
- {error, Reason} ->
- send_json(Req, 500, {[{error, to_binary(Reason)}]});
- {ok, {cancelled, RepId}} ->
- send_json(Req, 200, {[{ok, true}, {<<"_local_id">>, RepId}]});
- {ok, {continuous, RepId}} ->
- send_json(Req, 202, {[{ok, true}, {<<"_local_id">>, RepId}]});
- {ok, {HistoryResults}} ->
- send_json(Req, {[{ok, true} | HistoryResults]})
- end;
-
-handle_req(Req) ->
- send_method_not_allowed(Req, "POST").
-
-
-handle_scheduler_docs(Db, Req) when is_binary(Db) ->
- VArgs0 = couch_mrview_http:parse_params(Req, undefined),
- StatesQs = chttpd:qs_value(Req, "states"),
- States = couch_replicator_httpd_util:parse_replication_state_filter(StatesQs),
- VArgs1 = VArgs0#mrargs{
- view_type = map,
- include_docs = true,
- reduce = false,
- extra = [{filter_states, States}]
- },
- VArgs2 = couch_mrview_util:validate_args(VArgs1),
- Opts = [{user_ctx, Req#httpd.user_ctx}],
- Max = chttpd:chunked_response_buffer_size(),
- Acc = couch_replicator_httpd_util:docs_acc_new(Req, Db, Max),
- Cb = fun couch_replicator_httpd_util:docs_cb/2,
- {ok, RAcc} = couch_replicator_fabric:docs(Db, Opts, VArgs2, Cb, Acc),
- {ok, couch_replicator_httpd_util:docs_acc_response(RAcc)}.
-
-
-handle_scheduler_doc(Db, DocId, Req) when is_binary(Db), is_binary(DocId) ->
- UserCtx = Req#httpd.user_ctx,
- case couch_replicator:doc(Db, DocId, UserCtx#user_ctx.roles) of
- {ok, DocInfo} ->
- send_json(Req, couch_replicator_httpd_util:update_db_name(DocInfo));
- {error, not_found} ->
- throw(not_found)
- end.
-
-
-parse_unquoted_docs_path([_, _ | _] = Unquoted) ->
- DbAndAfter = lists:dropwhile(fun(E) -> E =/= ?REPDB end, Unquoted),
- BeforeRDb = lists:takewhile(fun(E) -> E =/= ?REPDB end, Unquoted),
- case DbAndAfter of
- [] ->
- {error, invalid};
- [?REPDB] ->
- {db_only, filename:join(BeforeRDb ++ [?REPDB])};
- [?REPDB, DocId] ->
- {db_and_doc, filename:join(BeforeRDb ++ [?REPDB]), DocId}
- end.
-
-
--ifdef(TEST).
-
--include_lib("eunit/include/eunit.hrl").
-
-unquoted_scheduler_docs_path_test_() ->
- [?_assertEqual(Res, parse_unquoted_docs_path(Path)) || {Res, Path} <- [
- {{error, invalid}, [<<"a">>,<< "b">>]},
- {{db_only, <<"a/_replicator">>}, [<<"a">>, ?REPDB]},
- {{db_only, <<"a/b/_replicator">>}, [<<"a">>, <<"b">>, ?REPDB]},
- {{db_and_doc, <<"_replicator">>, <<"x">>}, [?REPDB, <<"x">>]},
- {{db_and_doc, <<"a/_replicator">>, <<"x">>}, [<<"a">>, ?REPDB, <<"x">>]},
- {{error, invalid}, [<<"a/_replicator">>,<<"x">>]}
- ]].
-
--endif.