From e83bbb331a35f3439c53ced356abea837df42bd9 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Jun 23 2014 11:21:35 +0000 Subject: Ver. 4.0.1 Signed-off-by: Peter Lemenkov --- diff --git a/.gitignore b/.gitignore index f2d5afc..86cd50b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ cmullaparthi-ibrowse-07153bc.tar.gz /cmullaparthi-ibrowse-v2.1.0-0-gd5d3f1f.tar.gz /cmullaparthi-ibrowse-v2.1.3-0-g9c4f414.tar.gz /cmullaparthi-ibrowse-v2.2.0-0-g8c46b10.tar.gz +/ibrowse-4.0.1.tar.gz diff --git a/erlang-ibrowse-0001-Support-SOCKS5-protocol-for-replication.patch b/erlang-ibrowse-0001-Support-SOCKS5-protocol-for-replication.patch new file mode 100644 index 0000000..06447ab --- /dev/null +++ b/erlang-ibrowse-0001-Support-SOCKS5-protocol-for-replication.patch @@ -0,0 +1,287 @@ +From 56b181026ef328c4025b3f3cd65c48aa0ac5c47b Mon Sep 17 00:00:00 2001 +From: Robert Newson +Date: Sat, 4 Jan 2014 17:32:00 +0000 +Subject: [PATCH] Support SOCKS5 protocol for replication + +Using "socks5" as the protocol in the "proxy" parameter of replication +requests will cause DNS resolution and data transfer to happen via a +SOCKS5 proxy server. + +COUCHDB-2025 + +diff --git a/src/ibrowse_http_client.erl b/src/ibrowse_http_client.erl +index 59b9e08..8a3ce49 100644 +--- a/src/ibrowse_http_client.erl ++++ b/src/ibrowse_http_client.erl +@@ -39,7 +39,8 @@ + + -record(state, {host, port, connect_timeout, + inactivity_timer_ref, +- use_proxy = false, proxy_auth_digest, ++ use_http_proxy = false, http_proxy_auth_digest, ++ socks5_host, socks5_port, socks5_user, socks5_password, + ssl_options = [], is_ssl = false, socket, + proxy_tunnel_setup = false, + tunnel_setup_queue = [], +@@ -488,9 +489,21 @@ handle_sock_closed(#state{reply_buffer = Buf, reqs = Reqs, http_status_code = SC + State + end. + +-do_connect(Host, Port, Options, #state{is_ssl = true, +- use_proxy = false, +- ssl_options = SSLOptions}, ++do_connect(Host, Port, Options, #state{socks5_host = SocksHost}=State, Timeout) ++ when SocksHost /= undefined -> ++ ProxyOptions = [ ++ {user, State#state.socks5_user}, ++ {password, State#state.socks5_password}, ++ {host, SocksHost}, ++ {port, State#state.socks5_port}, ++ {is_ssl, State#state.is_ssl}, ++ {ssl_opts, State#state.ssl_options}], ++ ibrowse_socks5:connect(Host, Port, ProxyOptions, ++ get_sock_options(SocksHost, Options, []), ++ Timeout); ++do_connect(Host, Port, Options, #state{is_ssl = true, ++ use_http_proxy = false, ++ ssl_options = SSLOptions}, + Timeout) -> + ssl:connect(Host, Port, get_sock_options(Host, Options, SSLOptions), Timeout); + do_connect(Host, Port, Options, _State, Timeout) -> +@@ -541,7 +554,7 @@ filter_sock_options(Opts) -> + + do_send(Req, #state{socket = Sock, + is_ssl = true, +- use_proxy = true, ++ use_http_proxy = true, + proxy_tunnel_setup = Pts}) when Pts /= done -> gen_tcp:send(Sock, Req); + do_send(Req, #state{socket = Sock, is_ssl = true}) -> ssl:send(Sock, Req); + do_send(Req, #state{socket = Sock, is_ssl = false}) -> gen_tcp:send(Sock, Req). +@@ -589,7 +602,7 @@ maybe_chunked_encode(Data, true) -> + do_close(#state{socket = undefined}) -> ok; + do_close(#state{socket = Sock, + is_ssl = true, +- use_proxy = true, ++ use_http_proxy = true, + proxy_tunnel_setup = Pts + }) when Pts /= done -> catch gen_tcp:close(Sock); + do_close(#state{socket = Sock, is_ssl = true}) -> catch ssl:close(Sock); +@@ -602,7 +615,7 @@ active_once(#state{socket = Socket} = State) -> + + do_setopts(_Sock, [], _) -> ok; + do_setopts(Sock, Opts, #state{is_ssl = true, +- use_proxy = true, ++ use_http_proxy = true, + proxy_tunnel_setup = Pts} + ) when Pts /= done -> inet:setopts(Sock, Opts); + do_setopts(Sock, Opts, #state{is_ssl = true}) -> ssl:setopts(Sock, Opts); +@@ -621,17 +634,28 @@ send_req_1(From, + port = Port} = Url, + Headers, Method, Body, Options, Timeout, + #state{socket = undefined} = State) -> ++ ProxyHost = get_value(proxy_host, Options, false), ++ ProxyProtocol = get_value(proxy_protocol, Options, http), + {Host_1, Port_1, State_1} = +- case get_value(proxy_host, Options, false) of +- false -> ++ case {ProxyHost, ProxyProtocol} of ++ {false, _} -> + {Host, Port, State}; +- PHost -> ++ {_, http} -> + ProxyUser = get_value(proxy_user, Options, []), + ProxyPassword = get_value(proxy_password, Options, []), + Digest = http_auth_digest(ProxyUser, ProxyPassword), +- {PHost, get_value(proxy_port, Options, 80), +- State#state{use_proxy = true, +- proxy_auth_digest = Digest}} ++ {ProxyHost, get_value(proxy_port, Options, 80), ++ State#state{use_http_proxy = true, ++ http_proxy_auth_digest = Digest}}; ++ {_, socks5} -> ++ ProxyUser = list_to_binary(get_value(proxy_user, Options, [])), ++ ProxyPassword = list_to_binary(get_value(proxy_password, Options, [])), ++ ProxyPort = get_value(proxy_port, Options, 1080), ++ {Host, Port, ++ State#state{socks5_host = ProxyHost, ++ socks5_port = ProxyPort, ++ socks5_user = ProxyUser, ++ socks5_password = ProxyPassword}} + end, + State_2 = check_ssl_options(Options, State_1), + do_trace("Connecting...~n", []), +@@ -662,7 +686,7 @@ send_req_1(From, + Headers, Method, Body, Options, Timeout, + #state{ + proxy_tunnel_setup = false, +- use_proxy = true, ++ use_http_proxy = true, + is_ssl = true} = State) -> + Ref = case Timeout of + infinity -> +@@ -850,11 +874,11 @@ add_auth_headers(#url{username = User, + end, + add_proxy_auth_headers(State, Headers_1). + +-add_proxy_auth_headers(#state{use_proxy = false}, Headers) -> ++add_proxy_auth_headers(#state{use_http_proxy = false}, Headers) -> + Headers; +-add_proxy_auth_headers(#state{proxy_auth_digest = []}, Headers) -> ++add_proxy_auth_headers(#state{http_proxy_auth_digest = []}, Headers) -> + Headers; +-add_proxy_auth_headers(#state{proxy_auth_digest = Auth_digest}, Headers) -> ++add_proxy_auth_headers(#state{http_proxy_auth_digest = Auth_digest}, Headers) -> + [{"Proxy-Authorization", ["Basic ", Auth_digest]} | Headers]. + + http_auth_digest([], []) -> +@@ -863,7 +887,7 @@ http_auth_digest(Username, Password) -> + ibrowse_lib:encode_base64(Username ++ [$: | Password]). + + make_request(Method, Headers, AbsPath, RelPath, Body, Options, +- #state{use_proxy = UseProxy, is_ssl = Is_ssl}, ReqId) -> ++ #state{use_http_proxy = UseHttpProxy, is_ssl = Is_ssl}, ReqId) -> + HttpVsn = http_vsn_string(get_value(http_vsn, Options, {1,1})), + Fun1 = fun({X, Y}) when is_atom(X) -> + {to_lower(atom_to_list(X)), X, Y}; +@@ -906,7 +930,7 @@ make_request(Method, Headers, AbsPath, RelPath, Body, Options, + Headers_2 + end, + Headers_4 = cons_headers(Headers_3), +- Uri = case get_value(use_absolute_uri, Options, false) or UseProxy of ++ Uri = case get_value(use_absolute_uri, Options, false) or UseHttpProxy of + true -> + case Is_ssl of + true -> +diff --git a/src/ibrowse_lib.erl b/src/ibrowse_lib.erl +index 1ce6bd4..7b12cb3 100644 +--- a/src/ibrowse_lib.erl ++++ b/src/ibrowse_lib.erl +@@ -362,9 +362,10 @@ parse_url([], get_password, Url, TmpAcc) -> + parse_url([], State, Url, TmpAcc) -> + {invalid_uri_2, State, Url, TmpAcc}. + +-default_port(http) -> 80; +-default_port(https) -> 443; +-default_port(ftp) -> 21. ++default_port(socks5) -> 1080; ++default_port(http) -> 80; ++default_port(https) -> 443; ++default_port(ftp) -> 21. + + printable_date() -> + {{Y,Mo,D},{H, M, S}} = calendar:local_time(), +diff --git a/src/ibrowse_socks5.erl b/src/ibrowse_socks5.erl +new file mode 100644 +index 0000000..d00df44 +--- /dev/null ++++ b/src/ibrowse_socks5.erl +@@ -0,0 +1,109 @@ ++% 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(ibrowse_socks5). ++ ++-define(VERSION, 5). ++-define(CONNECT, 1). ++ ++-define(NO_AUTH, 0). ++-define(USERPASS, 2). ++-define(UNACCEPTABLE, 16#FF). ++-define(RESERVED, 0). ++ ++-define(ATYP_IPV4, 1). ++-define(ATYP_DOMAINNAME, 3). ++-define(ATYP_IPV6, 4). ++ ++-define(SUCCEEDED, 0). ++ ++-export([connect/5]). ++ ++-import(ibrowse_lib, [get_value/2, get_value/3]). ++ ++connect(TargetHost, TargetPort, ProxyOptions, Options, Timeout) -> ++ case gen_tcp:connect(get_value(host, ProxyOptions), ++ get_value(port, ProxyOptions), ++ Options, Timeout) of ++ {ok, Socket} -> ++ case handshake(Socket, Options) of ++ ok -> ++ case connect(TargetHost, TargetPort, Socket) of ++ ok -> ++ maybe_ssl(Socket, ProxyOptions, Timeout); ++ Else -> ++ gen_tcp:close(Socket), ++ Else ++ end; ++ Else -> ++ gen_tcp:close(Socket), ++ Else ++ end; ++ Else -> ++ Else ++ end. ++ ++handshake(Socket, ProxyOptions) when is_port(Socket) -> ++ {Handshake, Success} = case get_value(user, ProxyOptions, <<>>) of ++ <<>> -> ++ {<>, ?NO_AUTH}; ++ User -> ++ Password = get_value(password, ProxyOptions, <<>>), ++ {<>, ?USERPASS} ++ end, ++ ok = gen_tcp:send(Socket, Handshake), ++ case gen_tcp:recv(Socket, 0) of ++ {ok, <>} -> ++ ok; ++ {ok, <>} -> ++ {error, unacceptable}; ++ {error, Reason} -> ++ {error, Reason} ++ end. ++ ++connect(Host, Port, Via) when is_list(Host) -> ++ connect(list_to_binary(Host), Port, Via); ++connect(Host, Port, Via) when is_binary(Host), is_integer(Port), ++ is_port(Via) -> ++ ok = gen_tcp:send(Via, ++ <>), ++ case gen_tcp:recv(Via, 0) of ++ {ok, <>} -> ++ ok; ++ {ok, <>} -> ++ {error, rep(Rep)}; ++ {error, Reason} -> ++ {error, Reason} ++ end. ++ ++maybe_ssl(Socket, ProxyOptions, Timeout) -> ++ IsSsl = get_value(is_ssl, ProxyOptions, false), ++ SslOpts = get_value(ssl_opts, ProxyOptions, []), ++ case IsSsl of ++ false -> ++ {ok, Socket}; ++ true -> ++ ssl:connect(Socket, SslOpts, Timeout) ++ end. ++ ++rep(0) -> succeeded; ++rep(1) -> server_fail; ++rep(2) -> disallowed_by_ruleset; ++rep(3) -> network_unreachable; ++rep(4) -> host_unreachable; ++rep(5) -> connection_refused; ++rep(6) -> ttl_expired; ++rep(7) -> command_not_supported; ++rep(8) -> address_type_not_supported. diff --git a/erlang-ibrowse.spec b/erlang-ibrowse.spec index a8e3a43..6d9727b 100644 --- a/erlang-ibrowse.spec +++ b/erlang-ibrowse.spec @@ -1,63 +1,48 @@ %global realname ibrowse %global debug_package %{nil} -%global git_tag 8c46b10 Name: erlang-%{realname} -Version: 2.2.0 -Release: 9%{?dist} +Version: 4.0.1 +Release: 1%{?dist} Summary: Erlang HTTP client Group: Development/Languages License: BSD or LGPLv2+ URL: http://github.com/cmullaparthi/ibrowse -# wget --no-check-certificate https://github.com/cmullaparthi/ibrowse/tarball/v2.1.3 -Source0: cmullaparthi-%{realname}-v%{version}-0-g%{git_tag}.tar.gz -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -BuildRequires: erlang-erts -BuildRequires: erlang-eunit -%if 0%{?el6}%{?fc14}%{?fc15}%{?fc16} -# FIXME +VCS: scm:git:https://github.com/cmullaparthi/ibrowse.git +Source0: https://github.com/cmullaparthi/ibrowse/archive/v%{version}/%{realname}-%{version}.tar.gz +# CouchDB-specific patch +Patch1: erlang-ibrowse-0001-Support-SOCKS5-protocol-for-replication.patch BuildRequires: erlang-rebar -%endif BuildRequires: sed Requires: erlang-erts Requires: erlang-kernel -Requires: erlang-sasl Requires: erlang-ssl Requires: erlang-stdlib %description -Erlang HTTP client. +%{summary}. %prep -%setup -q -n cmullaparthi-%{realname}-%{git_tag} -iconv -f iso8859-1 -t utf-8 README > README.utf8 && \ - mv -f README.utf8 README || rm -f README.utf8 -rm -f ebin/%{realname}.app +%setup -q -n %{realname}-%{version} -# FIX version -sed -i -e "s,\"2.1.3\",\"2.2.0\",g" src/ibrowse.app.src +# Use system-wide rebar +sed -i -e "s,./rebar,rebar,g" Makefile -# Wait until we'll add rebar to EL-5 -#sed -i -e "s,./rebar,rebar -v,g" Makefile +%patch1 -p1 -b .socks5 %build -make %{?_smp_mflags} +CFLAGS="%{optflags}" REBAR_FLAGS="--verbose 2" make %{?_smp_mflags} %install -rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT%{_libdir}/erlang rm -f $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}_test.beam sed -i -e "s,\,ibrowse_test,,g" $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}.app -install -p -m 0644 -D src/ibrowse.hrl $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/include/ibrowse.hrl - - -%clean -rm -rf $RPM_BUILD_ROOT +install -p -m 0644 -D include/ibrowse.hrl $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/include/ibrowse.hrl %check @@ -65,8 +50,8 @@ make test %files -%defattr(-,root,root,-) -%doc BSD_LICENSE LICENSE README +%doc BSD_LICENSE LICENSE +%doc CHANGELOG CONTRIBUTORS README.md %dir %{_libdir}/erlang/lib/%{realname}-%{version} %dir %{_libdir}/erlang/lib/%{realname}-%{version}/ebin %dir %{_libdir}/erlang/lib/%{realname}-%{version}/include @@ -76,11 +61,17 @@ make test %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}_http_client.beam %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}_lb.beam %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}_lib.beam +%{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}_socks5.beam %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}_sup.beam %{_libdir}/erlang/lib/%{realname}-%{version}/include/%{realname}.hrl %changelog +* Mon Jun 23 2014 Peter Lemenkov - 4.0.1-1 +- Ver. 4.0.1 +- Support only Fedora 18+, EL6+ +- Added patch for CouchDB 1.6.0 + * Sat Jun 07 2014 Fedora Release Engineering - 2.2.0-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild diff --git a/sources b/sources index cfddb8e..72ecaec 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -7e7cfcde09e5ee1b63d617f7c30132f8 cmullaparthi-ibrowse-v2.2.0-0-g8c46b10.tar.gz +b3e1cd30e6e966f11321e8322a37214a ibrowse-4.0.1.tar.gz