You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/02/12 07:15:44 UTC

[1/7] couch commit: updated refs/heads/import-master to bc467c3

Updated Branches:
  refs/heads/import-master [created] bc467c323


Export missing function - couch_httpd:send_error/2

Signed-off-by: Peter Lemenkov <le...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/ba65b47a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/ba65b47a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/ba65b47a

Branch: refs/heads/import-master
Commit: ba65b47a822057b84e65f61fe196c5c1bdd65cad
Parents: ae8612b
Author: Peter Lemenkov <le...@gmail.com>
Authored: Fri Jan 10 15:30:54 2014 +0400
Committer: Peter Lemenkov <le...@gmail.com>
Committed: Fri Jan 10 15:30:54 2014 +0400

----------------------------------------------------------------------
 couch_httpd.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/ba65b47a/couch_httpd.erl
----------------------------------------------------------------------
diff --git a/couch_httpd.erl b/couch_httpd.erl
index 28932ba..465bc7a 100644
--- a/couch_httpd.erl
+++ b/couch_httpd.erl
@@ -27,7 +27,7 @@
 -export([start_chunked_response/3,send_chunk/2,log_request/2]).
 -export([start_response_length/4, start_response/3, send/2]).
 -export([start_json_response/2, start_json_response/3, end_json_response/1]).
--export([send_response/4,send_method_not_allowed/2,send_error/4, send_redirect/2,send_chunked_error/2]).
+-export([send_response/4,send_method_not_allowed/2,send_error/2,send_error/4, send_redirect/2,send_chunked_error/2]).
 -export([send_json/2,send_json/3,send_json/4,last_chunk/1,parse_multipart_request/3]).
 -export([accepted_encodings/1,handle_request_int/5,validate_referer/1,validate_ctype/2]).
 -export([http_1_0_keep_alive/2]).


[2/7] couch commit: updated refs/heads/import-master to bc467c3

Posted by da...@apache.org.
Move addition of qs params after normalization

This refactor executes normalize_path/1 before appending the bound query
string parameters.

COUCHDB-2031


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/832293ba
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/832293ba
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/832293ba

Branch: refs/heads/import-master
Commit: 832293badab4ff2c0346c37c9f63eeab1ac58cfc
Parents: ba65b47
Author: Adam Kocoloski <ad...@cloudant.com>
Authored: Sat Jan 18 00:31:49 2014 -0500
Committer: Adam Kocoloski <ad...@cloudant.com>
Committed: Sat Jan 18 00:31:49 2014 -0500

----------------------------------------------------------------------
 couch_httpd_rewrite.erl | 54 ++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/832293ba/couch_httpd_rewrite.erl
----------------------------------------------------------------------
diff --git a/couch_httpd_rewrite.erl b/couch_httpd_rewrite.erl
index 1187397..4354215 100644
--- a/couch_httpd_rewrite.erl
+++ b/couch_httpd_rewrite.erl
@@ -143,36 +143,32 @@ handle_rewrite_req(#httpd{
             DispatchList =  [make_rule(Rule) || {Rule} <- Rules],
             Method1 = couch_util:to_binary(Method),
 
-            %% get raw path by matching url to a rule.
-            RawPath = case try_bind_path(DispatchList, Method1, 
-                    PathParts, QueryList) of
-                no_dispatch_path ->
-                    throw(not_found);
-                {NewPathParts, Bindings} ->
-                    Parts = [quote_plus(X) || X <- NewPathParts],
-
-                    % build new path, reencode query args, eventually convert
-                    % them to json
-                    Bindings1 = maybe_encode_bindings(Bindings),
-                    Path = binary_to_list(
-                        iolist_to_binary([
-                                string:join(Parts, [?SEPARATOR]),
-                                [["?", mochiweb_util:urlencode(Bindings1)] 
-                                    || Bindings1 =/= [] ]
-                            ])),
-                    
-                    % if path is relative detect it and rewrite path
-                    case mochiweb_util:safe_relative_path(Path) of
-                        undefined ->
-                            ?b2l(Prefix) ++ "/" ++ Path;
-                        P1 ->
-                            ?b2l(Prefix) ++ "/" ++ P1
-                    end
+            % get raw path by matching url to a rule. Throws not_found.
+            {NewPathParts0, Bindings0} =
+                try_bind_path(DispatchList, Method1, PathParts, QueryList),
+            NewPathParts = [quote_plus(X) || X <- NewPathParts0],
+            Bindings = maybe_encode_bindings(Bindings0),
+
+            Path0 = string:join(NewPathParts, [?SEPARATOR]),
+
+            % if path is relative detect it and rewrite path
+            Path1 = case mochiweb_util:safe_relative_path(Path0) of
+                undefined ->
+                    ?b2l(Prefix) ++ "/" ++ Path0;
+                P1 ->
+                    ?b2l(Prefix) ++ "/" ++ P1
+            end,
+
+            Path2 = normalize_path(Path1),
 
-                end,
+            Path3 = case Bindings of
+                [] ->
+                    Path2;
+                _ ->
+                    [Path2, "?", mochiweb_util:urlencode(Bindings)]
+            end,
 
-            % normalize final path (fix levels "." and "..")
-            RawPath1 = ?b2l(iolist_to_binary(normalize_path(RawPath))),
+            RawPath1 = ?b2l(iolist_to_binary(Path3)),
 
             % In order to do OAuth correctly, we have to save the
             % requested path. We use default so chained rewriting
@@ -216,7 +212,7 @@ quote_plus(X) ->
 %% @doc Try to find a rule matching current url. If none is found
 %% 404 error not_found is raised
 try_bind_path([], _Method, _PathParts, _QueryList) ->
-    no_dispatch_path;
+    throw(not_found);
 try_bind_path([Dispatch|Rest], Method, PathParts, QueryList) ->
     [{PathParts1, Method1}, RedirectPath, QueryArgs, Formats] = Dispatch,
     case bind_method(Method1, Method) of


[4/7] couch commit: updated refs/heads/import-master to bc467c3

Posted by da...@apache.org.
Adopt to the recent erlang-oauth (1.3+)

Signed-off-by: Peter Lemenkov <le...@gmail.com>
Signed-off-by: Alexander Shorin <kx...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/529e4162
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/529e4162
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/529e4162

Branch: refs/heads/import-master
Commit: 529e41621dd95c8d176b4d18a47d14779cfcf5dd
Parents: 589936c
Author: Peter Lemenkov <le...@gmail.com>
Authored: Fri Jan 10 16:30:25 2014 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Wed Jan 29 04:18:16 2014 +0400

----------------------------------------------------------------------
 couch_httpd_oauth.erl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/529e4162/couch_httpd_oauth.erl
----------------------------------------------------------------------
diff --git a/couch_httpd_oauth.erl b/couch_httpd_oauth.erl
index 2094c08..60a937c 100644
--- a/couch_httpd_oauth.erl
+++ b/couch_httpd_oauth.erl
@@ -43,6 +43,7 @@ oauth_auth_callback(#httpd{mochi_req = MochiReq} = Req, CbParams) ->
     Method = atom_to_list(MochiReq:get(method)),
     #callback_params{
         consumer = Consumer,
+        token = Token,
         token_secret = TokenSecret,
         url = Url,
         signature = Sig,
@@ -61,7 +62,7 @@ oauth_auth_callback(#httpd{mochi_req = MochiReq} = Req, CbParams) ->
             "Consumer is `~p`, token secret is `~p`~n"
             "Expected signature was `~p`~n",
             [User, Sig, Method, Url, Params, Consumer, TokenSecret,
-                oauth:signature(Method, Url, Params, Consumer, TokenSecret)]),
+                oauth:sign(Method, Url, Params, Consumer, Token, TokenSecret)]),
         Req
     end.
 


[6/7] couch commit: updated refs/heads/import-master to bc467c3

Posted by da...@apache.org.
Throw cleaner error on MD5 mismatch during compaction

COUCHDB-2040


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/1ebec99c
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/1ebec99c
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/1ebec99c

Branch: refs/heads/import-master
Commit: 1ebec99c7a76bbdf0d7594628acf35768f6e2b5f
Parents: 88d4171
Author: Robert Newson <rn...@apache.org>
Authored: Wed Jan 29 21:47:58 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Jan 30 11:39:07 2014 +0000

----------------------------------------------------------------------
 couch_db_updater.erl | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/1ebec99c/couch_db_updater.erl
----------------------------------------------------------------------
diff --git a/couch_db_updater.erl b/couch_db_updater.erl
index af7578e..947669c 100644
--- a/couch_db_updater.erl
+++ b/couch_db_updater.erl
@@ -824,14 +824,16 @@ copy_doc_attachments(#db{updater_fd = SrcFd} = SrcDb, SrcSp, DestFd) ->
     end,
     % copy the bin values
     NewBinInfos = lists:map(
-        fun({Name, Type, BinSp, AttLen, RevPos, Md5}) ->
+        fun({Name, Type, BinSp, AttLen, RevPos, ExpectedMd5}) ->
             % 010 UPGRADE CODE
-            {NewBinSp, AttLen, AttLen, Md5, _IdentityMd5} =
+            {NewBinSp, AttLen, AttLen, ActualMd5, _IdentityMd5} =
                 couch_stream:copy_to_new_stream(SrcFd, BinSp, DestFd),
-            {Name, Type, NewBinSp, AttLen, AttLen, RevPos, Md5, identity};
-        ({Name, Type, BinSp, AttLen, DiskLen, RevPos, Md5, Enc1}) ->
-            {NewBinSp, AttLen, _, Md5, _IdentityMd5} =
+            check_md5(ExpectedMd5, ActualMd5),
+            {Name, Type, NewBinSp, AttLen, AttLen, RevPos, ExpectedMd5, identity};
+        ({Name, Type, BinSp, AttLen, DiskLen, RevPos, ExpectedMd5, Enc1}) ->
+            {NewBinSp, AttLen, _, ActualMd5, _IdentityMd5} =
                 couch_stream:copy_to_new_stream(SrcFd, BinSp, DestFd),
+            check_md5(ExpectedMd5, ActualMd5),
             Enc = case Enc1 of
             true ->
                 % 0110 UPGRADE CODE
@@ -842,10 +844,13 @@ copy_doc_attachments(#db{updater_fd = SrcFd} = SrcDb, SrcSp, DestFd) ->
             _ ->
                 Enc1
             end,
-            {Name, Type, NewBinSp, AttLen, DiskLen, RevPos, Md5, Enc}
+            {Name, Type, NewBinSp, AttLen, DiskLen, RevPos, ExpectedMd5, Enc}
         end, BinInfos),
     {BodyData, NewBinInfos}.
 
+check_md5(Md5, Md5) -> ok;
+check_md5(_, _) -> throw(md5_mismatch).
+
 copy_docs(Db, #db{updater_fd = DestFd} = NewDb, InfoBySeq0, Retry) ->
     % COUCHDB-968, make sure we prune duplicates during compaction
     InfoBySeq = lists:usort(fun(#doc_info{id=A}, #doc_info{id=B}) -> A =< B end,


[3/7] couch commit: updated refs/heads/import-master to bc467c3

Posted by da...@apache.org.
Speed up and move couch_httpd:find_in_binary.

See https://issues.apache.org/jira/browse/COUCHDB-1953


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/589936c4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/589936c4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/589936c4

Branch: refs/heads/import-master
Commit: 589936c445ff272eb07782369cf4b3378f595d3f
Parents: 832293b
Author: NickNorth <No...@gmail.com>
Authored: Tue Dec 3 20:58:53 2013 +0000
Committer: NickNorth <No...@gmail.com>
Committed: Sat Jan 25 16:19:50 2014 +0000

----------------------------------------------------------------------
 couch_httpd.erl | 30 +-----------------------------
 couch_util.erl  | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/589936c4/couch_httpd.erl
----------------------------------------------------------------------
diff --git a/couch_httpd.erl b/couch_httpd.erl
index 465bc7a..9245f4b 100644
--- a/couch_httpd.erl
+++ b/couch_httpd.erl
@@ -1003,7 +1003,7 @@ split_header(Line) ->
      mochiweb_util:parse_header(Value)}].
 
 read_until(#mp{data_fun=DataFun, buffer=Buffer}=Mp, Pattern, Callback) ->
-    case find_in_binary(Pattern, Buffer) of
+    case couch_util:find_in_binary(Pattern, Buffer) of
     not_found ->
         Callback2 = Callback(Buffer),
         {Buffer2, DataFun2} = DataFun(),
@@ -1079,34 +1079,6 @@ check_for_last(#mp{buffer=Buffer, data_fun=DataFun}=Mp) ->
                 data_fun = DataFun2})
     end.
 
-find_in_binary(_B, <<>>) ->
-    not_found;
-
-find_in_binary(B, Data) ->
-    case binary:match(Data, [B], []) of
-    nomatch ->
-        partial_find(binary:part(B, {0, byte_size(B) - 1}),
-                     binary:part(Data, {byte_size(Data), -byte_size(Data) + 1}), 1);
-    {Pos, _Len} ->
-        {exact, Pos}
-    end.
-
-partial_find(<<>>, _Data, _Pos) ->
-    not_found;
-
-partial_find(B, Data, N) when byte_size(Data) > 0 ->
-    case binary:match(Data, [B], []) of
-    nomatch ->
-        partial_find(binary:part(B, {0, byte_size(B) - 1}),
-                     binary:part(Data, {byte_size(Data), -byte_size(Data) + 1}), N + 1);
-    {Pos, _Len} ->
-        {partial, N + Pos}
-    end;
-
-partial_find(_B, _Data, _N) ->
-    not_found.
-
-
 validate_bind_address(Address) ->
     case inet_parse:address(Address) of
         {ok, _} -> ok;

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/589936c4/couch_util.erl
----------------------------------------------------------------------
diff --git a/couch_util.erl b/couch_util.erl
index afe3528..2509bef 100644
--- a/couch_util.erl
+++ b/couch_util.erl
@@ -29,6 +29,7 @@
 -export([encode_doc_id/1]).
 -export([with_db/2]).
 -export([rfc1123_date/0, rfc1123_date/1]).
+-export([find_in_binary/2]).
 
 -include("couch_db.hrl").
 
@@ -487,3 +488,34 @@ month(9) -> "Sep";
 month(10) -> "Oct";
 month(11) -> "Nov";
 month(12) -> "Dec".
+
+
+find_in_binary(_B, <<>>) ->
+    not_found;
+
+find_in_binary(B, Data) ->
+    case binary:match(Data, [B], []) of
+    nomatch ->
+        MatchLength = erlang:min(byte_size(B), byte_size(Data)),
+        match_prefix_at_end(binary:part(B, {0, MatchLength}),
+                            binary:part(Data, {byte_size(Data), -MatchLength}),
+                            MatchLength, byte_size(Data) - MatchLength);
+    {Pos, _Len} ->
+        {exact, Pos}
+    end.
+
+match_prefix_at_end(Prefix, Data, PrefixLength, N) ->
+    FirstCharMatches = binary:matches(Data, [binary:part(Prefix, {0, 1})], []),
+    match_rest_of_prefix(FirstCharMatches, Prefix, Data, PrefixLength, N).
+
+match_rest_of_prefix([], _Prefix, _Data, _PrefixLength, _N) ->
+    not_found;
+
+match_rest_of_prefix([{Pos, _Len} | Rest], Prefix, Data, PrefixLength, N) ->
+    case binary:match(binary:part(Data, {PrefixLength, Pos - PrefixLength}),
+                      [binary:part(Prefix, {0, PrefixLength - Pos})], []) of
+        nomatch ->
+            match_rest_of_prefix(Rest, Prefix, Data, PrefixLength, N);
+        {_Pos, _Len1} ->
+            {partial, N + Pos}
+    end.


[7/7] couch commit: updated refs/heads/import-master to bc467c3

Posted by da...@apache.org.
Accept gzipped JSON request bodies

COUCHDB-2054


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/bc467c32
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/bc467c32
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/bc467c32

Branch: refs/heads/import-master
Commit: bc467c323f8a09d0bf563739cd57a0596006968a
Parents: 1ebec99
Author: Robert Newson <rn...@apache.org>
Authored: Fri Feb 7 20:33:57 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Feb 7 20:33:57 2014 +0000

----------------------------------------------------------------------
 couch_httpd.erl | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/bc467c32/couch_httpd.erl
----------------------------------------------------------------------
diff --git a/couch_httpd.erl b/couch_httpd.erl
index acc20d7..f00fdd0 100644
--- a/couch_httpd.erl
+++ b/couch_httpd.erl
@@ -544,7 +544,7 @@ body(#httpd{req_body=ReqBody}) ->
     ReqBody.
 
 json_body(Httpd) ->
-    ?JSON_DECODE(body(Httpd)).
+    ?JSON_DECODE(maybe_decompress(Httpd, body(Httpd))).
 
 json_body_obj(Httpd) ->
     case json_body(Httpd) of
@@ -554,6 +554,15 @@ json_body_obj(Httpd) ->
     end.
 
 
+maybe_decompress(Httpd, Body) ->
+    case header_value(Httpd, "Content-Encoding", "identity") of
+    "gzip" ->
+        zlib:gunzip(Body);
+    "identity" ->
+        Body;
+    Else ->
+        throw({bad_ctype, [Else, " is not a supported content encoding."]})
+    end.
 
 doc_etag(#doc{revs={Start, [DiskRev|_]}}) ->
     "\"" ++ ?b2l(couch_doc:rev_to_str({Start, DiskRev})) ++ "\"".


[5/7] couch commit: updated refs/heads/import-master to bc467c3

Posted by da...@apache.org.
Allow cacertfile without verifying peers

COUCHDB-2028


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/88d4171c
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/88d4171c
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/88d4171c

Branch: refs/heads/import-master
Commit: 88d4171c209cfbbe87be430a3380a98d3fd327b6
Parents: 529e416
Author: Robert Newson <rn...@apache.org>
Authored: Sun Jan 12 11:57:41 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Jan 30 11:38:53 2014 +0000

----------------------------------------------------------------------
 couch_httpd.erl | 81 +++++++++++++++++++++-------------------------------
 1 file changed, 33 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/88d4171c/couch_httpd.erl
----------------------------------------------------------------------
diff --git a/couch_httpd.erl b/couch_httpd.erl
index 9245f4b..acc20d7 100644
--- a/couch_httpd.erl
+++ b/couch_httpd.erl
@@ -39,57 +39,42 @@ start_link(http) ->
     start_link(?MODULE, [{port, Port}]);
 start_link(https) ->
     Port = couch_config:get("ssl", "port", "6984"),
-    CertFile = couch_config:get("ssl", "cert_file", nil),
-    KeyFile = couch_config:get("ssl", "key_file", nil),
-    Options = case CertFile /= nil andalso KeyFile /= nil of
+    ServerOpts0 =
+        [{cacertfile, couch_config:get("ssl", "cacert_file", nil)},
+         {keyfile, couch_config:get("ssl", "key_file", nil)},
+         {certfile, couch_config:get("ssl", "cert_file", nil)},
+         {password, couch_config:get("ssl", "password", nil)}],
+
+    case (couch_util:get_value(keyfile, ServerOpts0) == nil orelse
+        couch_util:get_value(certfile, ServerOpts0) == nil) of
         true ->
-            SslOpts = [{certfile, CertFile}, {keyfile, KeyFile}],
-
-            %% set password if one is needed for the cert
-            SslOpts1 = case couch_config:get("ssl", "password", nil) of
-                nil -> SslOpts;
-                Password ->
-                    SslOpts ++ [{password, Password}]
-            end,
-            % do we verify certificates ?
-            FinalSslOpts = case couch_config:get("ssl",
-                    "verify_ssl_certificates", "false") of
-                "false" -> SslOpts1;
-                "true" ->
-                    case couch_config:get("ssl",
-                            "cacert_file", nil) of
-                        nil ->
-                            io:format("Verify SSL certificate "
-                                ++"enabled but file containing "
-                                ++"PEM encoded CA certificates is "
-                                ++"missing", []),
-                            throw({error, missing_cacerts});
-                        CaCertFile ->
-                            Depth = list_to_integer(couch_config:get("ssl",
-                                    "ssl_certificate_max_depth",
-                                    "1")),
-                            FinalOpts = [
-                                {cacertfile, CaCertFile},
-                                {depth, Depth},
-                                {verify, verify_peer}],
-                            % allows custom verify fun.
-                            case couch_config:get("ssl",
-                                    "verify_fun", nil) of
-                                nil -> FinalOpts;
-                                SpecStr ->
-                                    FinalOpts
-                                    ++ [{verify_fun, make_arity_3_fun(SpecStr)}]
-                            end
-                    end
-            end,
-
-            [{port, Port},
-                {ssl, true},
-                {ssl_opts, FinalSslOpts}];
-        false ->
             io:format("SSL enabled but PEM certificates are missing.", []),
-            throw({error, missing_certs})
+            throw({error, missing_certs});
+        false ->
+            ok
     end,
+
+    ServerOpts = [Opt || {_, V}=Opt <- ServerOpts0, V /= nil],
+
+    ClientOpts = case couch_config:get("ssl", "verify_ssl_certificates", "false") of
+        "false" ->
+            [];
+        "true" ->
+            [{depth, list_to_integer(couch_config:get("ssl",
+                "ssl_certificate_max_depth", "1"))},
+             {verify, verify_peer}] ++
+            case couch_config:get("ssl", "verify_fun", nil) of
+                nil -> [];
+                SpecStr ->
+                    [{verify_fun, make_arity_3_fun(SpecStr)}]
+            end
+    end,
+    SslOpts = ServerOpts ++ ClientOpts,
+
+    Options =
+        [{port, Port},
+         {ssl, true},
+         {ssl_opts, SslOpts}],
     start_link(https, Options).
 start_link(Name, Options) ->
     % read config and register for configuration changes