couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fdman...@apache.org
Subject svn commit: r1091709 - in /couchdb/trunk/src/ibrowse: Makefile.am ibrowse.app.in ibrowse.hrl ibrowse_http_client.erl ibrowse_lib.erl
Date Wed, 13 Apr 2011 08:50:58 GMT
Author: fdmanana
Date: Wed Apr 13 08:50:58 2011
New Revision: 1091709

URL: http://svn.apache.org/viewvc?rev=1091709&view=rev
Log:
Add support for replication over IPv6 (part 1)

This change upgrades ibrowse to version 2.2.0. This version adds support
for IPv6 (https://github.com/cmullaparthi/ibrowse/pull/34).
This is part of COUCHDB-665.


Modified:
    couchdb/trunk/src/ibrowse/Makefile.am
    couchdb/trunk/src/ibrowse/ibrowse.app.in
    couchdb/trunk/src/ibrowse/ibrowse.hrl
    couchdb/trunk/src/ibrowse/ibrowse_http_client.erl
    couchdb/trunk/src/ibrowse/ibrowse_lib.erl

Modified: couchdb/trunk/src/ibrowse/Makefile.am
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/ibrowse/Makefile.am?rev=1091709&r1=1091708&r2=1091709&view=diff
==============================================================================
--- couchdb/trunk/src/ibrowse/Makefile.am (original)
+++ couchdb/trunk/src/ibrowse/Makefile.am Wed Apr 13 08:50:58 2011
@@ -10,7 +10,7 @@
 ## License for the specific language governing permissions and limitations under
 ## the License.
 
-ibrowseebindir = $(localerlanglibdir)/ibrowse-2.1.3/ebin
+ibrowseebindir = $(localerlanglibdir)/ibrowse-2.2.0/ebin
 
 ibrowse_file_collection = \
 	ibrowse.app.in \

Modified: couchdb/trunk/src/ibrowse/ibrowse.app.in
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/ibrowse/ibrowse.app.in?rev=1091709&r1=1091708&r2=1091709&view=diff
==============================================================================
--- couchdb/trunk/src/ibrowse/ibrowse.app.in (original)
+++ couchdb/trunk/src/ibrowse/ibrowse.app.in Wed Apr 13 08:50:58 2011
@@ -1,6 +1,6 @@
 {application, ibrowse,
         [{description, "HTTP client application"},
-         {vsn, "2.1.3"},
+         {vsn, "2.2.0"},
          {modules, [ ibrowse, 
 		     ibrowse_http_client, 
 		     ibrowse_app, 

Modified: couchdb/trunk/src/ibrowse/ibrowse.hrl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/ibrowse/ibrowse.hrl?rev=1091709&r1=1091708&r2=1091709&view=diff
==============================================================================
--- couchdb/trunk/src/ibrowse/ibrowse.hrl (original)
+++ couchdb/trunk/src/ibrowse/ibrowse.hrl Wed Apr 13 08:50:58 2011
@@ -1,7 +1,16 @@
 -ifndef(IBROWSE_HRL).
 -define(IBROWSE_HRL, "ibrowse.hrl").
 
--record(url, {abspath, host, port, username, password, path, protocol}).
+-record(url, {
+          abspath,
+          host,
+          port,
+          username,
+          password,
+          path,
+          protocol,
+          host_type  % 'hostname', 'ipv4_address' or 'ipv6_address'
+}).
 
 -record(lb_pid, {host_port, pid}).
 

Modified: couchdb/trunk/src/ibrowse/ibrowse_http_client.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/ibrowse/ibrowse_http_client.erl?rev=1091709&r1=1091708&r2=1091709&view=diff
==============================================================================
--- couchdb/trunk/src/ibrowse/ibrowse_http_client.erl (original)
+++ couchdb/trunk/src/ibrowse/ibrowse_http_client.erl Wed Apr 13 08:50:58 2011
@@ -35,6 +35,7 @@
         ]).
 
 -include("ibrowse.hrl").
+-include_lib("kernel/include/inet.hrl").
 
 -record(state, {host, port, connect_timeout,
                 inactivity_timer_ref,
@@ -489,13 +490,19 @@ do_connect(Host, Port, Options, #state{i
                                        use_proxy   = false,
                                        ssl_options = SSLOptions},
            Timeout) ->
-    ssl:connect(Host, Port, get_sock_options(Options, SSLOptions), Timeout);
+    ssl:connect(Host, Port, get_sock_options(Host, Options, SSLOptions), Timeout);
 do_connect(Host, Port, Options, _State, Timeout) ->
-    gen_tcp:connect(Host, Port, get_sock_options(Options, []), Timeout).
+    gen_tcp:connect(Host, Port, get_sock_options(Host, Options, []), Timeout).
 
-get_sock_options(Options, SSLOptions) ->
+get_sock_options(Host, Options, SSLOptions) ->
     Caller_socket_options = get_value(socket_options, Options, []),
-    Other_sock_options = filter_sock_options(SSLOptions ++ Caller_socket_options),
+    Ipv6Options = case is_ipv6_host(Host) of
+        true ->
+            [inet6];
+        false ->
+            []
+    end,
+    Other_sock_options = filter_sock_options(SSLOptions ++ Caller_socket_options ++ Ipv6Options),
     case lists:keysearch(nodelay, 1, Other_sock_options) of
         false ->
             [{nodelay, true}, binary, {active, false} | Other_sock_options];
@@ -503,6 +510,21 @@ get_sock_options(Options, SSLOptions) ->
             [binary, {active, false} | Other_sock_options]
     end.
 
+is_ipv6_host(Host) ->
+    case inet_parse:address(Host) of
+        {ok, {_, _, _, _, _, _, _, _}} ->
+            true;
+        {ok, {_, _, _, _}} ->
+            false;
+        _  ->
+            case inet:gethostbyname(Host) of
+                {ok, #hostent{h_addrtype = inet6}} ->
+                    true;
+                _ ->
+                    false
+            end
+    end.
+
 %% We don't want the caller to specify certain options
 filter_sock_options(Opts) ->
     lists:filter(fun({active, _}) ->
@@ -1278,7 +1300,12 @@ handle_response(#request{from=From, stre
                        reply_buffer  = RepBuf,
                        recvd_headers = RespHeaders}=State) when SaveResponseToFile /= false
->
     Body = RepBuf,
-    ok = file:close(Fd),
+    case Fd of
+        undefined -> 
+            ok;
+        _ -> 
+            ok = file:close(Fd)
+    end,
     ResponseBody = case TmpFilename of
                        undefined ->
                            Body;

Modified: couchdb/trunk/src/ibrowse/ibrowse_lib.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/ibrowse/ibrowse_lib.erl?rev=1091709&r1=1091708&r2=1091709&view=diff
==============================================================================
--- couchdb/trunk/src/ibrowse/ibrowse_lib.erl (original)
+++ couchdb/trunk/src/ibrowse/ibrowse_lib.erl Wed Apr 13 08:50:58 2011
@@ -180,7 +180,19 @@ get_value(Tag, TVL) ->
     V.
 
 parse_url(Url) ->
-    parse_url(Url, get_protocol, #url{abspath=Url}, []).
+    case parse_url(Url, get_protocol, #url{abspath=Url}, []) of
+        #url{host_type = undefined, host = Host} = UrlRec ->
+            case inet_parse:address(Host) of
+                {ok, {_, _, _, _, _, _, _, _}} ->
+                    UrlRec#url{host_type = ipv6_address};
+                {ok, {_, _, _, _}} ->
+                    UrlRec#url{host_type = ipv4_address};
+                _ ->
+                    UrlRec#url{host_type = hostname}
+            end;
+        Else ->
+            Else
+    end.
 
 parse_url([$:, $/, $/ | _], get_protocol, Url, []) ->
     {invalid_uri_1, Url};
@@ -215,6 +227,21 @@ parse_url([$@ | T], get_username, Url, T
               Url#url{username = lists:reverse(TmpAcc),
                       password = ""},
               []);
+parse_url([$[ | T], get_username, Url, []) ->
+    % IPv6 address literals are enclosed by square brackets:
+    %     http://www.ietf.org/rfc/rfc2732.txt
+    parse_url(T, get_ipv6_address, Url#url{host_type = ipv6_address}, []);
+parse_url([$[ | T], get_username, _Url, TmpAcc) ->
+    {error, {invalid_username_or_host, lists:reverse(TmpAcc) ++ "[" ++ T}};
+parse_url([$[ | _], get_password, _Url, []) ->
+    {error, missing_password};
+parse_url([$[ | T], get_password, Url, TmpAcc) ->
+    % IPv6 address literals are enclosed by square brackets:
+    %     http://www.ietf.org/rfc/rfc2732.txt
+    parse_url(T, get_ipv6_address,
+              Url#url{host_type = ipv6_address,
+                      password = lists:reverse(TmpAcc)},
+              []);
 parse_url([$@ | T], get_password, Url, TmpAcc) ->
     parse_url(T, get_host, 
               Url#url{password = lists:reverse(TmpAcc)},
@@ -236,6 +263,28 @@ parse_url([H | T], get_password, Url, Tm
             username = undefined,
             password = undefined,
            path = Path};
+parse_url([$] | T], get_ipv6_address, #url{protocol = Prot} = Url, TmpAcc) ->
+    Addr = lists:reverse(TmpAcc),
+    case inet_parse:address(Addr) of
+        {ok, {_, _, _, _, _, _, _, _}} ->
+            Url2 = Url#url{host = Addr, port = default_port(Prot)},
+            case T of
+                [$: | T2] ->
+                    parse_url(T2, get_port, Url2, []);
+                [$/ | T2] ->
+                    Url2#url{path = [$/ | T2]};
+                [$? | T2] ->
+                    Url2#url{path = [$/, $? | T2]};
+                [] ->
+                    Url2#url{path = "/"};
+                _ ->
+                    {error, {invalid_host, "[" ++ Addr ++ "]" ++ T}}
+            end;
+        _ ->
+            {error, {invalid_ipv6_address, Addr}}
+    end;
+parse_url([$[ | T], get_host, #url{} = Url, []) ->
+    parse_url(T, get_ipv6_address, Url#url{host_type = ipv6_address}, []);
 parse_url([$: | T], get_host, #url{} = Url, TmpAcc) ->
     parse_url(T, get_port, 
               Url#url{host = lists:reverse(TmpAcc)},



Mime
View raw message