[couchdb] Ver. 1.0.2
Peter Lemenkov
peter at fedoraproject.org
Sun Feb 13 13:53:25 UTC 2011
commit 37c7a4ca72d0547f331aa34234ca30b4e333aed9
Author: Peter Lemenkov <lemenkov at gmail.com>
Date: Sun Feb 13 16:53:10 2011 +0300
Ver. 1.0.2
Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
.gitignore | 1 +
...-doc-files-and-do-not-install-installatio.patch | 88 +
couchdb-0001-Force-init-script-installation.patch | 39 -
...002-Install-docs-into-versioned-directory.patch | 26 +
...db-0002-Install-into-erllibdir-by-default.patch | 34 -
...ories-to-search-for-place-for-init-script.patch | 46 +
...-0003-Remove-bundled-erlang-oauth-library.patch | 1004 ------
...db-0004-Install-into-erllibdir-by-default.patch | 35 +
...-0005-Remove-bundled-erlang-oauth-library.patch | 476 +++
... couchdb-0006-Remove-bundled-etap-library.patch | 553 +---
...uchdb-0007-Remove-bundled-ibrowse-library.patch | 3647 ++++++++++----------
...chdb-0008-Remove-bundled-mochiweb-library.patch | 616 +----
...ouchdb-0009-Fixes-for-system-wide-ibrowse.patch | 41 +-
couchdb-0010-Do-not-install-gzipped-docs.patch | 220 --
...> couchdb-0010-Remove-pid-file-after-stop.patch | 6 +-
...DB-while-it-was-being-opened-would-crash-.patch | 6 +-
... couchdb-0012-Change-respawn-timeout-to-0.patch | 6 +-
...-No-erlang-min-2-and-erlang-max-2-in-R12B.patch | 78 -
...3-Relax-curl-dependency-to-7.15-for-RHEL5.patch | 39 +-
couchdb.spec | 73 +-
sources | 2 +-
21 files changed, 2623 insertions(+), 4413 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 2156faf..388e708 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ apache-couchdb-0.11.1.tar.gz
apache-couchdb-1.0.0.tar.gz
apache-couchdb-1.0.1.tar.gz
/apache-couchdb-1.0.1.tar.gz
+/apache-couchdb-1.0.2.tar.gz
diff --git a/couchdb-0001-Do-not-gzip-doc-files-and-do-not-install-installatio.patch b/couchdb-0001-Do-not-gzip-doc-files-and-do-not-install-installatio.patch
new file mode 100644
index 0000000..eee73be
--- /dev/null
+++ b/couchdb-0001-Do-not-gzip-doc-files-and-do-not-install-installatio.patch
@@ -0,0 +1,88 @@
+From 0f86f6e868dbdcbf832f28639bdc4c23e3304799 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Sun, 13 Feb 2011 13:52:38 +0300
+Subject: [PATCH 01/13] Do not gzip doc-files and do not install installation instructions
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ Makefile.am | 57 +++++++++------------------------------------------------
+ 1 files changed, 9 insertions(+), 48 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 6530287..dc4b8ce 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -15,18 +15,15 @@ SUBDIRS = bin etc src share test var utils
+ ACLOCAL_AMFLAGS = -I m4
+
+ localdoc_DATA = \
+- AUTHORS.gz \
+- BUGS.gz \
+- CHANGES.gz \
+- DEVELOPERS.gz \
+- INSTALL.gz \
+- INSTALL.Unix.gz \
+- INSTALL.Windows.gz \
+- LICENSE.gz \
+- NEWS.gz \
+- NOTICE.gz \
+- README.gz \
+- THANKS.gz
++ AUTHORS \
++ BUGS \
++ CHANGES \
++ DEVELOPERS \
++ LICENSE \
++ NEWS \
++ NOTICE \
++ README \
++ THANKS
+
+ DISTCLEANFILES = $(localdoc_DATA)
+
+@@ -45,42 +42,6 @@ EXTRA_DIST = \
+ THANKS \
+ license.skip
+
+-AUTHORS.gz: $(top_srcdir)/AUTHORS
+- -gzip -9 < $< > $@
+-
+-BUGS.gz: $(top_srcdir)/BUGS
+- -gzip -9 < $< > $@
+-
+-CHANGES.gz: $(top_srcdir)/CHANGES
+- -gzip -9 < $< > $@
+-
+-DEVELOPERS.gz: $(top_srcdir)/DEVELOPERS
+- -gzip -9 < $< > $@
+-
+-INSTALL.gz: $(top_srcdir)/INSTALL
+- -gzip -9 < $< > $@
+-
+-INSTALL.Unix.gz: $(top_srcdir)/INSTALL.Unix
+- -gzip -9 < $< > $@
+-
+-INSTALL.Windows.gz: $(top_srcdir)/INSTALL.Windows
+- -gzip -9 < $< > $@
+-
+-LICENSE.gz: $(top_srcdir)/LICENSE
+- -gzip -9 < $< > $@
+-
+-NEWS.gz: $(top_srcdir)/NEWS
+- -gzip -9 < $< > $@
+-
+-NOTICE.gz: $(top_srcdir)/NOTICE
+- -gzip -9 < $< > $@
+-
+-README.gz: $(top_srcdir)/README
+- -gzip -9 < $< > $@
+-
+-THANKS.gz: $(top_srcdir)/THANKS
+- -gzip -9 < $< > $@
+-
+ check: dev
+ $(top_builddir)/test/etap/run
+
+--
+1.7.4
+
diff --git a/couchdb-0002-Install-docs-into-versioned-directory.patch b/couchdb-0002-Install-docs-into-versioned-directory.patch
new file mode 100644
index 0000000..4c3da00
--- /dev/null
+++ b/couchdb-0002-Install-docs-into-versioned-directory.patch
@@ -0,0 +1,26 @@
+From 71ba13a7fb4a06571152da599dae9fe7bcb18807 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Sun, 13 Feb 2011 14:06:12 +0300
+Subject: [PATCH 02/13] Install docs into versioned directory
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ configure.ac | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index c609a08..999f890 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -356,7 +356,7 @@ AC_SUBST([bug_uri], ["LOCAL_BUG_URI"])
+
+ AC_SUBST([localconfdir], [${sysconfdir}/${package_identifier}])
+ AC_SUBST([localdatadir], [${datadir}/${package_identifier}])
+-AC_SUBST([localdocdir], [${datadir}/doc/${package_identifier}])
++AC_SUBST([localdocdir], [${datadir}/doc/${package_identifier}-${version}])
+ AC_SUBST([locallibdir], [${libdir}/${package_identifier}])
+ AC_SUBST([localstatelibdir], [${localstatedir}/lib/${package_identifier}])
+ AC_SUBST([localstatelogdir], [${localstatedir}/log/${package_identifier}])
+--
+1.7.4
+
diff --git a/couchdb-0003-More-directories-to-search-for-place-for-init-script.patch b/couchdb-0003-More-directories-to-search-for-place-for-init-script.patch
new file mode 100644
index 0000000..3143220
--- /dev/null
+++ b/couchdb-0003-More-directories-to-search-for-place-for-init-script.patch
@@ -0,0 +1,46 @@
+From 80fea41e3912f06e76e487531533e6b77e25ad93 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Sun, 13 Feb 2011 14:21:20 +0300
+Subject: [PATCH 03/13] More directories to search for place for init-script
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ configure.ac | 16 +++++++++++-----
+ 1 files changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 999f890..4ac64f9 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -294,17 +294,23 @@ launchd_enabled=false
+
+ if test "$use_init" = "yes"; then
+ AC_MSG_CHECKING(location of init directory)
+- if test -d /etc/rc.d; then
++ if test -d /etc/rc.d/init.d; then
+ init_enabled=true
+- AC_SUBST([initdir], ['${sysconfdir}/rc.d'])
++ AC_SUBST([initdir], ['${sysconfdir}/rc.d/init.d'])
+ AC_MSG_RESULT(${initdir})
+ else
+- if test -d /etc/init.d; then
++ if test -d /etc/rc.d; then
+ init_enabled=true
+- AC_SUBST([initdir], ['${sysconfdir}/init.d'])
++ AC_SUBST([initdir], ['${sysconfdir}/rc.d'])
+ AC_MSG_RESULT(${initdir})
+ else
+- AC_MSG_RESULT(not found)
++ if test -d /etc/init.d; then
++ init_enabled=true
++ AC_SUBST([initdir], ['${sysconfdir}/init.d'])
++ AC_MSG_RESULT(${initdir})
++ else
++ AC_MSG_RESULT(not found)
++ fi
+ fi
+ fi
+ fi
+--
+1.7.4
+
diff --git a/couchdb-0004-Install-into-erllibdir-by-default.patch b/couchdb-0004-Install-into-erllibdir-by-default.patch
new file mode 100644
index 0000000..7bc61fd
--- /dev/null
+++ b/couchdb-0004-Install-into-erllibdir-by-default.patch
@@ -0,0 +1,35 @@
+From e25c39956757cd457737ae8cba60a488b259e582 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Sun, 13 Feb 2011 14:36:36 +0300
+Subject: [PATCH 04/13] Install into erllibdir by default
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 4ac64f9..248bff7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -363,7 +363,7 @@ AC_SUBST([bug_uri], ["LOCAL_BUG_URI"])
+ AC_SUBST([localconfdir], [${sysconfdir}/${package_identifier}])
+ AC_SUBST([localdatadir], [${datadir}/${package_identifier}])
+ AC_SUBST([localdocdir], [${datadir}/doc/${package_identifier}-${version}])
+-AC_SUBST([locallibdir], [${libdir}/${package_identifier}])
++AC_SUBST([locallibdir], [${libdir}])
+ AC_SUBST([localstatelibdir], [${localstatedir}/lib/${package_identifier}])
+ AC_SUBST([localstatelogdir], [${localstatedir}/log/${package_identifier}])
+ AC_SUBST([localstaterundir], [${localstatedir}/run/${package_identifier}])
+@@ -373,7 +373,7 @@ if test x${IS_WINDOWS} = xTRUE; then
+ AC_SUBST([locallibbindir], [${prefix}/bin])
+ AC_SUBST([localerlanglibdir], [${libdir}])
+ else
+- AC_SUBST([locallibbindir], [${locallibdir}/bin])
++ AC_SUBST([locallibbindir], [${locallibdir}/erlang/lib/couch-${version}/priv])
+ AC_SUBST([localerlanglibdir], [${locallibdir}/erlang/lib])
+ fi
+
+--
+1.7.4
+
diff --git a/couchdb-0005-Remove-bundled-erlang-oauth-library.patch b/couchdb-0005-Remove-bundled-erlang-oauth-library.patch
new file mode 100644
index 0000000..bf8be5a
--- /dev/null
+++ b/couchdb-0005-Remove-bundled-erlang-oauth-library.patch
@@ -0,0 +1,476 @@
+From e143c2fa083e07cf4c2f2997da10a025e8a26b45 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Sun, 13 Feb 2011 14:45:18 +0300
+Subject: [PATCH 05/13] Remove bundled erlang-oauth library
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ configure.ac | 1 -
+ src/Makefile.am | 2 +-
+ src/erlang-oauth/Makefile.am | 50 ----------------
+ src/erlang-oauth/oauth.app.in | 20 ------
+ src/erlang-oauth/oauth.erl | 107 ----------------------------------
+ src/erlang-oauth/oauth_hmac_sha1.erl | 11 ----
+ src/erlang-oauth/oauth_http.erl | 22 -------
+ src/erlang-oauth/oauth_plaintext.erl | 10 ---
+ src/erlang-oauth/oauth_rsa_sha1.erl | 30 ----------
+ src/erlang-oauth/oauth_unix.erl | 16 -----
+ src/erlang-oauth/oauth_uri.erl | 88 ----------------------------
+ test/etap/test_util.erl.in | 2 +-
+ 12 files changed, 2 insertions(+), 357 deletions(-)
+ delete mode 100644 src/erlang-oauth/Makefile.am
+ delete mode 100644 src/erlang-oauth/oauth.app.in
+ delete mode 100644 src/erlang-oauth/oauth.erl
+ delete mode 100644 src/erlang-oauth/oauth_hmac_sha1.erl
+ delete mode 100644 src/erlang-oauth/oauth_http.erl
+ delete mode 100644 src/erlang-oauth/oauth_plaintext.erl
+ delete mode 100644 src/erlang-oauth/oauth_rsa_sha1.erl
+ delete mode 100644 src/erlang-oauth/oauth_unix.erl
+ delete mode 100644 src/erlang-oauth/oauth_uri.erl
+
+diff --git a/configure.ac b/configure.ac
+index 248bff7..d506257 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -404,7 +404,6 @@ AC_CONFIG_FILES([src/Makefile])
+ AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
+ AC_CONFIG_FILES([src/couchdb/Makefile])
+ AC_CONFIG_FILES([src/couchdb/priv/Makefile])
+-AC_CONFIG_FILES([src/erlang-oauth/Makefile])
+ AC_CONFIG_FILES([src/etap/Makefile])
+ AC_CONFIG_FILES([src/ibrowse/Makefile])
+ AC_CONFIG_FILES([src/mochiweb/Makefile])
+diff --git a/src/Makefile.am b/src/Makefile.am
+index b9529f9..e577138 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -10,4 +10,4 @@
+ ## License for the specific language governing permissions and limitations under
+ ## the License.
+
+-SUBDIRS = couchdb erlang-oauth etap ibrowse mochiweb
++SUBDIRS = couchdb etap ibrowse mochiweb
+diff --git a/src/erlang-oauth/Makefile.am b/src/erlang-oauth/Makefile.am
+deleted file mode 100644
+index 48b7648..0000000
+--- a/src/erlang-oauth/Makefile.am
++++ /dev/null
+@@ -1,50 +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.
+-
+-oauthebindir = $(localerlanglibdir)/erlang-oauth/ebin
+-
+-oauth_file_collection = \
+- oauth.app.in \
+- oauth.erl \
+- oauth_hmac_sha1.erl \
+- oauth_http.erl \
+- oauth_plaintext.erl \
+- oauth_rsa_sha1.erl \
+- oauth_unix.erl \
+- oauth_uri.erl
+-
+-# Removed oauth_rsa_sha1.beam until we require R12B5 or
+-# we add a ./configure option to enable it.
+-
+-oauthebin_make_generated_file_list = \
+- oauth.app \
+- oauth.beam \
+- oauth_hmac_sha1.beam \
+- oauth_http.beam \
+- oauth_plaintext.beam \
+- oauth_unix.beam \
+- oauth_uri.beam
+-
+-oauthebin_DATA = \
+- $(oauthebin_make_generated_file_list)
+-
+-EXTRA_DIST = \
+- $(oauth_file_collection)
+-
+-CLEANFILES = \
+- $(oauthebin_make_generated_file_list)
+-
+-%.app: %.app.in
+- cp $< $@
+-
+-%.beam: %.erl
+- $(ERLC) $(ERLC_FLAGS) $<
+diff --git a/src/erlang-oauth/oauth.app.in b/src/erlang-oauth/oauth.app.in
+deleted file mode 100644
+index 6357b9b..0000000
+--- a/src/erlang-oauth/oauth.app.in
++++ /dev/null
+@@ -1,20 +0,0 @@
+-{application, oauth, [
+- {description, "Erlang OAuth implementation"},
+- {vsn, "dev"},
+- {modules, [
+- oauth,
+- oauth_hmac_sha1,
+- oauth_http,
+- oauth_plaintext,
+- oauth_rsa_sha1,
+- oauth_unix,
+- oauth_uri
+- ]},
+- {registered, []},
+- {applications, [
+- kernel,
+- stdlib,
+- crypto,
+- inets
+- ]}
+-]}.
+diff --git a/src/erlang-oauth/oauth.erl b/src/erlang-oauth/oauth.erl
+deleted file mode 100644
+index 866655c..0000000
+--- a/src/erlang-oauth/oauth.erl
++++ /dev/null
+@@ -1,107 +0,0 @@
+--module(oauth).
+-
+--export(
+- [ get/5
+- , header/1
+- , post/5
+- , signature/5
+- , signature_base_string/3
+- , signed_params/6
+- , token/1
+- , token_secret/1
+- , uri/2
+- , verify/6
+- ]).
+-
+-
+-get(URL, ExtraParams, Consumer, Token, TokenSecret) ->
+- SignedParams = signed_params("GET", URL, ExtraParams, Consumer, Token, TokenSecret),
+- oauth_http:get(uri(URL, SignedParams)).
+-
+-post(URL, ExtraParams, Consumer, Token, TokenSecret) ->
+- SignedParams = signed_params("POST", URL, ExtraParams, Consumer, Token, TokenSecret),
+- oauth_http:post(URL, oauth_uri:params_to_string(SignedParams)).
+-
+-uri(Base, []) ->
+- Base;
+-uri(Base, Params) ->
+- lists:concat([Base, "?", oauth_uri:params_to_string(Params)]).
+-
+-header(Params) ->
+- {"Authorization", "OAuth " ++ oauth_uri:params_to_header_string(Params)}.
+-
+-token(Params) ->
+- proplists:get_value("oauth_token", Params).
+-
+-token_secret(Params) ->
+- proplists:get_value("oauth_token_secret", Params).
+-
+-verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret) ->
+- case signature_method(Consumer) of
+- plaintext ->
+- oauth_plaintext:verify(Signature, consumer_secret(Consumer), TokenSecret);
+- hmac_sha1 ->
+- BaseString = signature_base_string(HttpMethod, URL, Params),
+- oauth_hmac_sha1:verify(Signature, BaseString, consumer_secret(Consumer), TokenSecret);
+- rsa_sha1 ->
+- BaseString = signature_base_string(HttpMethod, URL, Params),
+- oauth_rsa_sha1:verify(Signature, BaseString, consumer_secret(Consumer))
+- end.
+-
+-signed_params(HttpMethod, URL, ExtraParams, Consumer, Token, TokenSecret) ->
+- Params = token_param(Token, params(Consumer, ExtraParams)),
+- [{"oauth_signature", signature(HttpMethod, URL, Params, Consumer, TokenSecret)}|Params].
+-
+-signature(HttpMethod, URL, Params, Consumer, TokenSecret) ->
+- case signature_method(Consumer) of
+- plaintext ->
+- oauth_plaintext:signature(consumer_secret(Consumer), TokenSecret);
+- hmac_sha1 ->
+- BaseString = signature_base_string(HttpMethod, URL, Params),
+- oauth_hmac_sha1:signature(BaseString, consumer_secret(Consumer), TokenSecret);
+- rsa_sha1 ->
+- BaseString = signature_base_string(HttpMethod, URL, Params),
+- oauth_rsa_sha1:signature(BaseString, consumer_secret(Consumer))
+- end.
+-
+-signature_base_string(HttpMethod, URL, Params) ->
+- NormalizedURL = oauth_uri:normalize(URL),
+- NormalizedParams = oauth_uri:params_to_string(lists:sort(Params)),
+- oauth_uri:calate("&", [HttpMethod, NormalizedURL, NormalizedParams]).
+-
+-token_param("", Params) ->
+- Params;
+-token_param(Token, Params) ->
+- [{"oauth_token", Token}|Params].
+-
+-params(Consumer, Params) ->
+- Nonce = base64:encode_to_string(crypto:rand_bytes(32)), % cf. ruby-oauth
+- params(Consumer, oauth_unix:timestamp(), Nonce, Params).
+-
+-params(Consumer, Timestamp, Nonce, Params) ->
+- [ {"oauth_version", "1.0"}
+- , {"oauth_nonce", Nonce}
+- , {"oauth_timestamp", integer_to_list(Timestamp)}
+- , {"oauth_signature_method", signature_method_string(Consumer)}
+- , {"oauth_consumer_key", consumer_key(Consumer)}
+- | Params
+- ].
+-
+-signature_method_string(Consumer) ->
+- case signature_method(Consumer) of
+- plaintext ->
+- "PLAINTEXT";
+- hmac_sha1 ->
+- "HMAC-SHA1";
+- rsa_sha1 ->
+- "RSA-SHA1"
+- end.
+-
+-signature_method(_Consumer={_, _, Method}) ->
+- Method.
+-
+-consumer_secret(_Consumer={_, Secret, _}) ->
+- Secret.
+-
+-consumer_key(_Consumer={Key, _, _}) ->
+- Key.
+diff --git a/src/erlang-oauth/oauth_hmac_sha1.erl b/src/erlang-oauth/oauth_hmac_sha1.erl
+deleted file mode 100644
+index 79d59f3..0000000
+--- a/src/erlang-oauth/oauth_hmac_sha1.erl
++++ /dev/null
+@@ -1,11 +0,0 @@
+--module(oauth_hmac_sha1).
+-
+--export([signature/3, verify/4]).
+-
+-
+-signature(BaseString, CS, TS) ->
+- Key = oauth_uri:calate("&", [CS, TS]),
+- base64:encode_to_string(crypto:sha_mac(Key, BaseString)).
+-
+-verify(Signature, BaseString, CS, TS) ->
+- couch_util:verify(signature(BaseString, CS, TS), Signature).
+diff --git a/src/erlang-oauth/oauth_http.erl b/src/erlang-oauth/oauth_http.erl
+deleted file mode 100644
+index bf5a4ba..0000000
+--- a/src/erlang-oauth/oauth_http.erl
++++ /dev/null
+@@ -1,22 +0,0 @@
+--module(oauth_http).
+-
+--export([get/1, post/2, response_params/1, response_body/1, response_code/1]).
+-
+-
+-get(URL) ->
+- request(get, {URL, []}).
+-
+-post(URL, Data) ->
+- request(post, {URL, [], "application/x-www-form-urlencoded", Data}).
+-
+-request(Method, Request) ->
+- http:request(Method, Request, [{autoredirect, false}], []).
+-
+-response_params(Response) ->
+- oauth_uri:params_from_string(response_body(Response)).
+-
+-response_body({{_, _, _}, _, Body}) ->
+- Body.
+-
+-response_code({{_, Code, _}, _, _}) ->
+- Code.
+diff --git a/src/erlang-oauth/oauth_plaintext.erl b/src/erlang-oauth/oauth_plaintext.erl
+deleted file mode 100644
+index 41a1e9b..0000000
+--- a/src/erlang-oauth/oauth_plaintext.erl
++++ /dev/null
+@@ -1,10 +0,0 @@
+--module(oauth_plaintext).
+-
+--export([signature/2, verify/3]).
+-
+-
+-signature(CS, TS) ->
+- oauth_uri:calate("&", [CS, TS]).
+-
+-verify(Signature, CS, TS) ->
+- couch_util:verify(signature(CS, TS), Signature).
+diff --git a/src/erlang-oauth/oauth_rsa_sha1.erl b/src/erlang-oauth/oauth_rsa_sha1.erl
+deleted file mode 100644
+index 6f4828e..0000000
+--- a/src/erlang-oauth/oauth_rsa_sha1.erl
++++ /dev/null
+@@ -1,30 +0,0 @@
+--module(oauth_rsa_sha1).
+-
+--export([signature/2, verify/3]).
+-
+--include_lib("public_key/include/public_key.hrl").
+-
+-
+-signature(BaseString, PrivateKeyPath) ->
+- {ok, [Info]} = public_key:pem_to_der(PrivateKeyPath),
+- {ok, PrivateKey} = public_key:decode_private_key(Info),
+- base64:encode_to_string(public_key:sign(list_to_binary(BaseString), PrivateKey)).
+-
+-verify(Signature, BaseString, PublicKey) ->
+- public_key:verify_signature(to_binary(BaseString), sha, base64:decode(Signature), public_key(PublicKey)).
+-
+-to_binary(Term) when is_list(Term) ->
+- list_to_binary(Term);
+-to_binary(Term) when is_binary(Term) ->
+- Term.
+-
+-public_key(Path) when is_list(Path) ->
+- {ok, [{cert, DerCert, not_encrypted}]} = public_key:pem_to_der(Path),
+- {ok, Cert} = public_key:pkix_decode_cert(DerCert, otp),
+- public_key(Cert);
+-public_key(#'OTPCertificate'{tbsCertificate=Cert}) ->
+- public_key(Cert);
+-public_key(#'OTPTBSCertificate'{subjectPublicKeyInfo=Info}) ->
+- public_key(Info);
+-public_key(#'OTPSubjectPublicKeyInfo'{subjectPublicKey=Key}) ->
+- Key.
+diff --git a/src/erlang-oauth/oauth_unix.erl b/src/erlang-oauth/oauth_unix.erl
+deleted file mode 100644
+index 73ca314..0000000
+--- a/src/erlang-oauth/oauth_unix.erl
++++ /dev/null
+@@ -1,16 +0,0 @@
+--module(oauth_unix).
+-
+--export([timestamp/0]).
+-
+-
+-timestamp() ->
+- timestamp(calendar:universal_time()).
+-
+-timestamp(DateTime) ->
+- seconds(DateTime) - epoch().
+-
+-epoch() ->
+- seconds({{1970,1,1},{00,00,00}}).
+-
+-seconds(DateTime) ->
+- calendar:datetime_to_gregorian_seconds(DateTime).
+diff --git a/src/erlang-oauth/oauth_uri.erl b/src/erlang-oauth/oauth_uri.erl
+deleted file mode 100644
+index fb27ae7..0000000
+--- a/src/erlang-oauth/oauth_uri.erl
++++ /dev/null
+@@ -1,88 +0,0 @@
+--module(oauth_uri).
+-
+--export([normalize/1, calate/2, encode/1]).
+--export([params_from_string/1, params_to_string/1,
+- params_from_header_string/1, params_to_header_string/1]).
+-
+--import(lists, [concat/1]).
+-
+--define(is_uppercase_alpha(C), C >= $A, C =< $Z).
+--define(is_lowercase_alpha(C), C >= $a, C =< $z).
+--define(is_alpha(C), ?is_uppercase_alpha(C); ?is_lowercase_alpha(C)).
+--define(is_digit(C), C >= $0, C =< $9).
+--define(is_alphanumeric(C), ?is_alpha(C); ?is_digit(C)).
+--define(is_unreserved(C), ?is_alphanumeric(C); C =:= $-; C =:= $_; C =:= $.; C =:= $~).
+--define(is_hex(C), ?is_digit(C); C >= $A, C =< $F).
+-
+-
+-normalize(URI) ->
+- case http_uri:parse(URI) of
+- {Scheme, UserInfo, Host, Port, Path, _Query} ->
+- normalize(Scheme, UserInfo, string:to_lower(Host), Port, [Path]);
+- Else ->
+- Else
+- end.
+-
+-normalize(http, UserInfo, Host, 80, Acc) ->
+- normalize(http, UserInfo, [Host|Acc]);
+-normalize(https, UserInfo, Host, 443, Acc) ->
+- normalize(https, UserInfo, [Host|Acc]);
+-normalize(Scheme, UserInfo, Host, Port, Acc) ->
+- normalize(Scheme, UserInfo, [Host, ":", Port|Acc]).
+-
+-normalize(Scheme, [], Acc) ->
+- concat([Scheme, "://"|Acc]);
+-normalize(Scheme, UserInfo, Acc) ->
+- concat([Scheme, "://", UserInfo, "@"|Acc]).
+-
+-params_to_header_string(Params) ->
+- intercalate(", ", [concat([encode(K), "=\"", encode(V), "\""]) || {K, V} <- Params]).
+-
+-params_from_header_string(String) ->
+- [param_from_header_string(Param) || Param <- re:split(String, ",\\s*", [{return, list}]), Param =/= ""].
+-
+-param_from_header_string(Param) ->
+- [Key, QuotedValue] = string:tokens(Param, "="),
+- Value = string:substr(QuotedValue, 2, length(QuotedValue) - 2),
+- {decode(Key), decode(Value)}.
+-
+-params_from_string(Params) ->
+- [param_from_string(Param) || Param <- string:tokens(Params, "&")].
+-
+-param_from_string(Param) ->
+- list_to_tuple([decode(Value) || Value <- string:tokens(Param, "=")]).
+-
+-params_to_string(Params) ->
+- intercalate("&", [calate("=", [K, V]) || {K, V} <- Params]).
+-
+-calate(Sep, Xs) ->
+- intercalate(Sep, [encode(X) || X <- Xs]).
+-
+-intercalate(Sep, Xs) ->
+- concat(intersperse(Sep, Xs)).
+-
+-intersperse(_, []) -> [];
+-intersperse(_, [X]) -> [X];
+-intersperse(Sep, [X|Xs]) ->
+- [X, Sep|intersperse(Sep, Xs)].
+-
+-decode(Chars) ->
+- decode(Chars, []).
+-
+-decode([], Decoded) ->
+- lists:reverse(Decoded);
+-decode([$%,A,B|Etc], Decoded) when ?is_hex(A), ?is_hex(B) ->
+- decode(Etc, [erlang:list_to_integer([A,B], 16)|Decoded]);
+-decode([C|Etc], Decoded) when ?is_unreserved(C) ->
+- decode(Etc, [C|Decoded]).
+-
+-encode(Chars) ->
+- encode(Chars, []).
+-
+-encode([], Encoded) ->
+- lists:flatten(lists:reverse(Encoded));
+-encode([C|Etc], Encoded) when ?is_unreserved(C) ->
+- encode(Etc, [C|Encoded]);
+-encode([C|Etc], Encoded) ->
+- Value = io_lib:format("%~2.1.0s", [erlang:integer_to_list(C, 16)]),
+- encode(Etc, [Value|Encoded]).
+diff --git a/test/etap/test_util.erl.in b/test/etap/test_util.erl.in
+index 4c42edb..79b0417 100644
+--- a/test/etap/test_util.erl.in
++++ b/test/etap/test_util.erl.in
+@@ -22,7 +22,7 @@ builddir() ->
+ "@abs_top_builddir@".
+
+ init_code_path() ->
+- Paths = ["etap", "couchdb", "erlang-oauth", "ibrowse", "mochiweb"],
++ Paths = ["etap", "couchdb", "ibrowse", "mochiweb"],
+ lists:foreach(fun(Name) ->
+ code:add_pathz(filename:join([builddir(), "src", Name]))
+ end, Paths).
+--
+1.7.4
+
diff --git a/couchdb-0004-Remove-bundled-erlang-etap-library.patch b/couchdb-0006-Remove-bundled-etap-library.patch
similarity index 75%
rename from couchdb-0004-Remove-bundled-erlang-etap-library.patch
rename to couchdb-0006-Remove-bundled-etap-library.patch
index 9cc3460..c1c84a2 100644
--- a/couchdb-0004-Remove-bundled-erlang-etap-library.patch
+++ b/couchdb-0006-Remove-bundled-etap-library.patch
@@ -1,28 +1,25 @@
-From 138d0cc7848e305bbd0ad92aa352a9ca5d978164 Mon Sep 17 00:00:00 2001
+From 1cbf3cbc25d1b5f8cc411ba8410cfb0e83e1a71a Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
-Date: Wed, 14 Jul 2010 18:00:03 +0400
-Subject: [PATCH 04/13] Remove bundled erlang-etap library
+Date: Sun, 13 Feb 2011 14:46:37 +0300
+Subject: [PATCH 06/13] Remove bundled etap library
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
- configure | 3 -
configure.ac | 1 -
src/Makefile.am | 2 +-
- src/Makefile.in | 2 +-
- src/etap/Makefile.am | 44 ----
- src/etap/Makefile.in | 476 -----------------------------------------
- src/etap/etap.erl | 416 -----------------------------------
- src/etap/etap_application.erl | 72 ------
- src/etap/etap_can.erl | 79 -------
- src/etap/etap_exception.erl | 66 ------
+ src/etap/Makefile.am | 44 -----
+ src/etap/etap.erl | 416 -----------------------------------------
+ src/etap/etap_application.erl | 72 -------
+ src/etap/etap_can.erl | 79 --------
+ src/etap/etap_exception.erl | 66 -------
src/etap/etap_process.erl | 42 ----
- src/etap/etap_report.erl | 343 -----------------------------
- src/etap/etap_request.erl | 89 --------
- src/etap/etap_string.erl | 47 ----
- src/etap/etap_web.erl | 65 ------
+ src/etap/etap_report.erl | 343 ---------------------------------
+ src/etap/etap_request.erl | 89 ---------
+ src/etap/etap_string.erl | 47 -----
+ src/etap/etap_web.erl | 65 -------
test/etap/test_util.erl.in | 2 +-
- 16 files changed, 3 insertions(+), 1746 deletions(-)
+ 13 files changed, 2 insertions(+), 1266 deletions(-)
delete mode 100644 src/etap/Makefile.am
- delete mode 100644 src/etap/Makefile.in
delete mode 100644 src/etap/etap.erl
delete mode 100644 src/etap/etap_application.erl
delete mode 100644 src/etap/etap_can.erl
@@ -33,32 +30,11 @@ Subject: [PATCH 04/13] Remove bundled erlang-etap library
delete mode 100644 src/etap/etap_string.erl
delete mode 100644 src/etap/etap_web.erl
-diff --git a/configure b/configure
-index 5a205d2..a8d077e 100755
---- a/configure
-+++ b/configure
-@@ -12263,8 +12263,6 @@ ac_config_files="$ac_config_files src/couchdb/Makefile"
-
- ac_config_files="$ac_config_files src/couchdb/priv/Makefile"
-
--ac_config_files="$ac_config_files src/etap/Makefile"
--
- ac_config_files="$ac_config_files src/ibrowse/Makefile"
-
- ac_config_files="$ac_config_files src/mochiweb/Makefile"
-@@ -13291,7 +13289,6 @@ do
- "src/couchdb/couch.app.tpl") CONFIG_FILES="$CONFIG_FILES src/couchdb/couch.app.tpl" ;;
- "src/couchdb/Makefile") CONFIG_FILES="$CONFIG_FILES src/couchdb/Makefile" ;;
- "src/couchdb/priv/Makefile") CONFIG_FILES="$CONFIG_FILES src/couchdb/priv/Makefile" ;;
-- "src/etap/Makefile") CONFIG_FILES="$CONFIG_FILES src/etap/Makefile" ;;
- "src/ibrowse/Makefile") CONFIG_FILES="$CONFIG_FILES src/ibrowse/Makefile" ;;
- "src/mochiweb/Makefile") CONFIG_FILES="$CONFIG_FILES src/mochiweb/Makefile" ;;
- "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
diff --git a/configure.ac b/configure.ac
-index 8b31f54..7e25bc2 100644
+index d506257..7720633 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -388,7 +388,6 @@ AC_CONFIG_FILES([src/Makefile])
+@@ -404,7 +404,6 @@ AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
AC_CONFIG_FILES([src/couchdb/Makefile])
AC_CONFIG_FILES([src/couchdb/priv/Makefile])
@@ -76,19 +52,6 @@ index e577138..19a5d20 100644
-SUBDIRS = couchdb etap ibrowse mochiweb
+SUBDIRS = couchdb ibrowse mochiweb
-diff --git a/src/Makefile.in b/src/Makefile.in
-index 3fec89c..ae1b828 100644
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -248,7 +248,7 @@ version_minor = @version_minor@
- version_release = @version_release@
- version_revision = @version_revision@
- version_stage = @version_stage@
--SUBDIRS = couchdb etap ibrowse mochiweb
-+SUBDIRS = couchdb ibrowse mochiweb
- all: all-recursive
-
- .SUFFIXES:
diff --git a/src/etap/Makefile.am b/src/etap/Makefile.am
deleted file mode 100644
index 732347b..0000000
@@ -139,488 +102,6 @@ index 732347b..0000000
-
-%.beam: %.erl
- $(ERLC) $(ERLC_FLAGS) $<
-diff --git a/src/etap/Makefile.in b/src/etap/Makefile.in
-deleted file mode 100644
-index df91ff7..0000000
---- a/src/etap/Makefile.in
-+++ /dev/null
-@@ -1,476 +0,0 @@
--# Makefile.in generated by automake 1.11 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
--# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
--# Inc.
--# This Makefile.in is free software; the Free Software Foundation
--# gives unlimited permission to copy and/or distribute it,
--# with or without modifications, as long as this notice is preserved.
--
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
--# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
--# PARTICULAR PURPOSE.
--
-- at SET_MAKE@
--
--VPATH = @srcdir@
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@PACKAGE@
--am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
--install_sh_DATA = $(install_sh) -c -m 644
--install_sh_PROGRAM = $(install_sh) -c
--install_sh_SCRIPT = $(install_sh) -c
--INSTALL_HEADER = $(INSTALL_DATA)
--transform = $(program_transform_name)
--NORMAL_INSTALL = :
--PRE_INSTALL = :
--POST_INSTALL = :
--NORMAL_UNINSTALL = :
--PRE_UNINSTALL = :
--POST_UNINSTALL = :
--build_triplet = @build@
--host_triplet = @host@
--subdir = src/etap
--DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_curl.m4 \
-- $(top_srcdir)/m4/ac_check_icu.m4 $(top_srcdir)/m4/libtool.m4 \
-- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-- $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-- $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--SOURCES =
--DIST_SOURCES =
--am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
--am__vpath_adj = case $$p in \
-- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-- *) f=$$p;; \
-- esac;
--am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
--am__install_max = 40
--am__nobase_strip_setup = \
-- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
--am__nobase_strip = \
-- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
--am__nobase_list = $(am__nobase_strip_setup); \
-- for p in $$list; do echo "$$p $$p"; done | \
-- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-- if (++n[$$2] == $(am__install_max)) \
-- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-- END { for (dir in files) print dir, files[dir] }'
--am__base_list = \
-- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
--am__installdirs = "$(DESTDIR)$(etapebindir)"
--DATA = $(etapebin_DATA)
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AR = @AR@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CURL_CFLAGS = @CURL_CFLAGS@
--CURL_CONFIG = @CURL_CONFIG@
--CURL_LDFLAGS = @CURL_LDFLAGS@
--CURL_LIBS = @CURL_LIBS@
--CYGPATH_W = @CYGPATH_W@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--ERL = @ERL@
--ERLC = @ERLC@
--ERLC_FLAGS = @ERLC_FLAGS@
--EXEEXT = @EXEEXT@
--FGREP = @FGREP@
--FLAGS = @FLAGS@
--GREP = @GREP@
--HELP2MAN_EXECUTABLE = @HELP2MAN_EXECUTABLE@
--ICU_CFLAGS = @ICU_CFLAGS@
--ICU_CONFIG = @ICU_CONFIG@
--ICU_CXXFLAGS = @ICU_CXXFLAGS@
--ICU_LIBS = @ICU_LIBS@
--ICU_LOCAL_BIN = @ICU_LOCAL_BIN@
--ICU_LOCAL_CFLAGS = @ICU_LOCAL_CFLAGS@
--ICU_LOCAL_LDFLAGS = @ICU_LOCAL_LDFLAGS@
--INNO_COMPILER_EXECUTABLE = @INNO_COMPILER_EXECUTABLE@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--JSLIB = @JSLIB@
--JS_LIB_BASE = @JS_LIB_BASE@
--JS_LIB_BINARY = @JS_LIB_BINARY@
--JS_LIB_DIR = @JS_LIB_DIR@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAKEINFO = @MAKEINFO@
--MKDIR_P = @MKDIR_P@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--RANLIB = @RANLIB@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--VERSION = @VERSION@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--am__include = @am__include@
--am__leading_dot = @am__leading_dot@
--am__quote = @am__quote@
--am__tar = @am__tar@
--am__untar = @am__untar@
--bindir = @bindir@
--bug_uri = @bug_uri@
--build = @build@
--build_alias = @build_alias@
--build_cpu = @build_cpu@
--build_os = @build_os@
--build_vendor = @build_vendor@
--builddir = @builddir@
--datadir = @datadir@
--datarootdir = @datarootdir@
--docdir = @docdir@
--dvidir = @dvidir@
--exec_prefix = @exec_prefix@
--host = @host@
--host_alias = @host_alias@
--host_cpu = @host_cpu@
--host_os = @host_os@
--host_vendor = @host_vendor@
--htmldir = @htmldir@
--includedir = @includedir@
--infodir = @infodir@
--initdir = @initdir@
--install_sh = @install_sh@
--launchddir = @launchddir@
--libdir = @libdir@
--libexecdir = @libexecdir@
--localconfdir = @localconfdir@
--localdatadir = @localdatadir@
--localdocdir = @localdocdir@
--localedir = @localedir@
--localerlanglibdir = @localerlanglibdir@
--locallibbindir = @locallibbindir@
--locallibdir = @locallibdir@
--localstatedir = @localstatedir@
--localstatelibdir = @localstatelibdir@
--localstatelogdir = @localstatelogdir@
--localstaterundir = @localstaterundir@
--lt_ECHO = @lt_ECHO@
--mandir = @mandir@
--mkdir_p = @mkdir_p@
--msvc_redist_dir = @msvc_redist_dir@
--msvc_redist_name = @msvc_redist_name@
--oldincludedir = @oldincludedir@
--openssl_bin_dir = @openssl_bin_dir@
--package_author_address = @package_author_address@
--package_author_name = @package_author_name@
--package_identifier = @package_identifier@
--package_name = @package_name@
--package_tarname = @package_tarname@
--pdfdir = @pdfdir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--version = @version@
--version_major = @version_major@
--version_minor = @version_minor@
--version_release = @version_release@
--version_revision = @version_revision@
--version_stage = @version_stage@
--etapebindir = $(localerlanglibdir)/etap/ebin
--etap_file_collection = \
-- etap.erl \
-- etap_application.erl \
-- etap_can.erl \
-- etap_exception.erl \
-- etap_process.erl \
-- etap_report.erl \
-- etap_request.erl \
-- etap_string.erl \
-- etap_web.erl
--
--etapebin_make_generated_file_list = \
-- etap.beam \
-- etap_application.beam \
-- etap_can.beam \
-- etap_exception.beam \
-- etap_process.beam \
-- etap_report.beam \
-- etap_request.beam \
-- etap_string.beam \
-- etap_web.beam
--
--etapebin_DATA = $(etapebin_make_generated_file_list)
--EXTRA_DIST = $(etap_file_collection)
--CLEANFILES = $(etapebin_make_generated_file_list)
--all: all-am
--
--.SUFFIXES:
--$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
-- @for dep in $?; do \
-- case '$(am__configure_deps)' in \
-- *$$dep*) \
-- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-- && { if test -f $@; then exit 0; else break; fi; }; \
-- exit 1;; \
-- esac; \
-- done; \
-- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/etap/Makefile'; \
-- $(am__cd) $(top_srcdir) && \
-- $(AUTOMAKE) --foreign src/etap/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-- @case '$?' in \
-- *config.status*) \
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-- *) \
-- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-- esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure: $(am__configure_deps)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4): $(am__aclocal_m4_deps)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--mostlyclean-libtool:
-- -rm -f *.lo
--
--clean-libtool:
-- -rm -rf .libs _libs
--install-etapebinDATA: $(etapebin_DATA)
-- @$(NORMAL_INSTALL)
-- test -z "$(etapebindir)" || $(MKDIR_P) "$(DESTDIR)$(etapebindir)"
-- @list='$(etapebin_DATA)'; test -n "$(etapebindir)" || list=; \
-- for p in $$list; do \
-- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-- echo "$$d$$p"; \
-- done | $(am__base_list) | \
-- while read files; do \
-- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(etapebindir)'"; \
-- $(INSTALL_DATA) $$files "$(DESTDIR)$(etapebindir)" || exit $$?; \
-- done
--
--uninstall-etapebinDATA:
-- @$(NORMAL_UNINSTALL)
-- @list='$(etapebin_DATA)'; test -n "$(etapebindir)" || list=; \
-- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-- test -n "$$files" || exit 0; \
-- echo " ( cd '$(DESTDIR)$(etapebindir)' && rm -f" $$files ")"; \
-- cd "$(DESTDIR)$(etapebindir)" && rm -f $$files
--tags: TAGS
--TAGS:
--
--ctags: CTAGS
--CTAGS:
--
--
--distdir: $(DISTFILES)
-- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-- list='$(DISTFILES)'; \
-- dist_files=`for file in $$list; do echo $$file; done | \
-- sed -e "s|^$$srcdirstrip/||;t" \
-- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-- case $$dist_files in \
-- */*) $(MKDIR_P) `echo "$$dist_files" | \
-- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-- sort -u` ;; \
-- esac; \
-- for file in $$dist_files; do \
-- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-- if test -d $$d/$$file; then \
-- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-- if test -d "$(distdir)/$$file"; then \
-- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-- fi; \
-- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-- fi; \
-- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-- else \
-- test -f "$(distdir)/$$file" \
-- || cp -p $$d/$$file "$(distdir)/$$file" \
-- || exit 1; \
-- fi; \
-- done
--check-am: all-am
--check: check-am
--all-am: Makefile $(DATA)
--installdirs:
-- for dir in "$(DESTDIR)$(etapebindir)"; do \
-- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-- done
--install: install-am
--install-exec: install-exec-am
--install-data: install-data-am
--uninstall: uninstall-am
--
--install-am: all-am
-- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
--
--installcheck: installcheck-am
--install-strip:
-- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-- `test -z '$(STRIP)' || \
-- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
--mostlyclean-generic:
--
--clean-generic:
-- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
--
--distclean-generic:
-- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
-- @echo "This command is intended for maintainers to use"
-- @echo "it deletes files that may require special tools to rebuild."
--clean: clean-am
--
--clean-am: clean-generic clean-libtool mostlyclean-am
--
--distclean: distclean-am
-- -rm -f Makefile
--distclean-am: clean-am distclean-generic
--
--dvi: dvi-am
--
--dvi-am:
--
--html: html-am
--
--html-am:
--
--info: info-am
--
--info-am:
--
--install-data-am: install-etapebinDATA
--
--install-dvi: install-dvi-am
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-am
--
--install-html-am:
--
--install-info: install-info-am
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-am
--
--install-pdf-am:
--
--install-ps: install-ps-am
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-am
-- -rm -f Makefile
--maintainer-clean-am: distclean-am maintainer-clean-generic
--
--mostlyclean: mostlyclean-am
--
--mostlyclean-am: mostlyclean-generic mostlyclean-libtool
--
--pdf: pdf-am
--
--pdf-am:
--
--ps: ps-am
--
--ps-am:
--
--uninstall-am: uninstall-etapebinDATA
--
--.MAKE: install-am install-strip
--
--.PHONY: all all-am check check-am clean clean-generic clean-libtool \
-- distclean distclean-generic distclean-libtool distdir dvi \
-- dvi-am html html-am info info-am install install-am \
-- install-data install-data-am install-dvi install-dvi-am \
-- install-etapebinDATA install-exec install-exec-am install-html \
-- install-html-am install-info install-info-am install-man \
-- install-pdf install-pdf-am install-ps install-ps-am \
-- install-strip installcheck installcheck-am installdirs \
-- maintainer-clean maintainer-clean-generic mostlyclean \
-- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-- uninstall uninstall-am uninstall-etapebinDATA
--
--
--%.beam: %.erl
-- $(ERLC) $(ERLC_FLAGS) $<
--
--# Tell versions [3.59,3.63) of GNU make to not export all variables.
--# Otherwise a system limit (for SysV at least) may be exceeded.
--.NOEXPORT:
diff --git a/src/etap/etap.erl b/src/etap/etap.erl
deleted file mode 100644
index 5ad5dba..0000000
@@ -1908,5 +1389,5 @@ index 79b0417..c57d7a8 100644
code:add_pathz(filename:join([builddir(), "src", Name]))
end, Paths).
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0006-Remove-bundled-ibrowse-library.patch b/couchdb-0007-Remove-bundled-ibrowse-library.patch
similarity index 51%
rename from couchdb-0006-Remove-bundled-ibrowse-library.patch
rename to couchdb-0007-Remove-bundled-ibrowse-library.patch
index 46e5834..8c05a58 100644
--- a/couchdb-0006-Remove-bundled-ibrowse-library.patch
+++ b/couchdb-0007-Remove-bundled-ibrowse-library.patch
@@ -1,29 +1,25 @@
-From a69bb8849d0cc2d1e872a0334fde6a34ea7741b3 Mon Sep 17 00:00:00 2001
+From 591d1f9e3ecb65df3708a6846b3fff8f1964c5ea Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
-Date: Fri, 6 Aug 2010 16:05:02 +0400
-Subject: [PATCH 06/13] Remove bundled ibrowse library
+Date: Sun, 13 Feb 2011 14:47:57 +0300
+Subject: [PATCH 07/13] Remove bundled ibrowse library
Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
- configure | 3 -
configure.ac | 1 -
src/Makefile.am | 2 +-
- src/Makefile.in | 2 +-
- src/ibrowse/Makefile.am | 49 --
- src/ibrowse/Makefile.in | 484 ------------
+ src/ibrowse/Makefile.am | 49 -
src/ibrowse/ibrowse.app.in | 13 -
- src/ibrowse/ibrowse.erl | 760 ------------------
+ src/ibrowse/ibrowse.erl | 863 -----------------
src/ibrowse/ibrowse.hrl | 12 -
- src/ibrowse/ibrowse_app.erl | 64 --
- src/ibrowse/ibrowse_http_client.erl | 1476 -----------------------------------
- src/ibrowse/ibrowse_lb.erl | 216 -----
- src/ibrowse/ibrowse_lib.erl | 399 ----------
- src/ibrowse/ibrowse_sup.erl | 65 --
- src/ibrowse/ibrowse_test.erl | 377 ---------
+ src/ibrowse/ibrowse_app.erl | 63 --
+ src/ibrowse/ibrowse_http_client.erl | 1821 -----------------------------------
+ src/ibrowse/ibrowse_lb.erl | 235 -----
+ src/ibrowse/ibrowse_lib.erl | 342 -------
+ src/ibrowse/ibrowse_sup.erl | 63 --
+ src/ibrowse/ibrowse_test.erl | 519 ----------
test/etap/test_util.erl.in | 2 +-
- 16 files changed, 3 insertions(+), 3922 deletions(-)
+ 13 files changed, 2 insertions(+), 3983 deletions(-)
delete mode 100644 src/ibrowse/Makefile.am
- delete mode 100644 src/ibrowse/Makefile.in
delete mode 100644 src/ibrowse/ibrowse.app.in
delete mode 100644 src/ibrowse/ibrowse.erl
delete mode 100644 src/ibrowse/ibrowse.hrl
@@ -34,65 +30,31 @@ Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
delete mode 100644 src/ibrowse/ibrowse_sup.erl
delete mode 100644 src/ibrowse/ibrowse_test.erl
-diff --git a/configure b/configure
-index e82813c..3fbc92b 100755
---- a/configure
-+++ b/configure
-@@ -12263,8 +12263,6 @@ ac_config_files="$ac_config_files src/couchdb/Makefile"
-
- ac_config_files="$ac_config_files src/couchdb/priv/Makefile"
-
--ac_config_files="$ac_config_files src/ibrowse/Makefile"
--
- ac_config_files="$ac_config_files test/Makefile"
-
- ac_config_files="$ac_config_files test/bench/Makefile"
-@@ -13287,7 +13285,6 @@ do
- "src/couchdb/couch.app.tpl") CONFIG_FILES="$CONFIG_FILES src/couchdb/couch.app.tpl" ;;
- "src/couchdb/Makefile") CONFIG_FILES="$CONFIG_FILES src/couchdb/Makefile" ;;
- "src/couchdb/priv/Makefile") CONFIG_FILES="$CONFIG_FILES src/couchdb/priv/Makefile" ;;
-- "src/ibrowse/Makefile") CONFIG_FILES="$CONFIG_FILES src/ibrowse/Makefile" ;;
- "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
- "test/bench/Makefile") CONFIG_FILES="$CONFIG_FILES test/bench/Makefile" ;;
- "test/etap/Makefile") CONFIG_FILES="$CONFIG_FILES test/etap/Makefile" ;;
diff --git a/configure.ac b/configure.ac
-index 157d8c0..905f6d1 100644
+index 7720633..4b2c94e 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -388,7 +388,6 @@ AC_CONFIG_FILES([src/Makefile])
+@@ -404,7 +404,6 @@ AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
AC_CONFIG_FILES([src/couchdb/Makefile])
AC_CONFIG_FILES([src/couchdb/priv/Makefile])
-AC_CONFIG_FILES([src/ibrowse/Makefile])
+ AC_CONFIG_FILES([src/mochiweb/Makefile])
AC_CONFIG_FILES([test/Makefile])
AC_CONFIG_FILES([test/bench/Makefile])
- AC_CONFIG_FILES([test/etap/Makefile])
diff --git a/src/Makefile.am b/src/Makefile.am
-index 5a6646f..753b177 100644
+index 19a5d20..d50341a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,4 +10,4 @@
## License for the specific language governing permissions and limitations under
## the License.
--SUBDIRS = couchdb ibrowse
-+SUBDIRS = couchdb
-diff --git a/src/Makefile.in b/src/Makefile.in
-index 2d11fc8..93c5f43 100644
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -248,7 +248,7 @@ version_minor = @version_minor@
- version_release = @version_release@
- version_revision = @version_revision@
- version_stage = @version_stage@
--SUBDIRS = couchdb ibrowse
-+SUBDIRS = couchdb
- all: all-recursive
-
- .SUFFIXES:
+-SUBDIRS = couchdb ibrowse mochiweb
++SUBDIRS = couchdb mochiweb
diff --git a/src/ibrowse/Makefile.am b/src/ibrowse/Makefile.am
deleted file mode 100644
-index 510f36a..0000000
+index 4cebe5d..0000000
--- a/src/ibrowse/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
@@ -108,7 +70,7 @@ index 510f36a..0000000
-## License for the specific language governing permissions and limitations under
-## the License.
-
--ibrowseebindir = $(localerlanglibdir)/ibrowse-1.5.2/ebin
+-ibrowseebindir = $(localerlanglibdir)/ibrowse-2.1.2/ebin
-
-ibrowse_file_collection = \
- ibrowse.app.in \
@@ -145,509 +107,19 @@ index 510f36a..0000000
-
-%.beam: %.erl
- $(ERLC) $(ERLC_FLAGS) $<
-diff --git a/src/ibrowse/Makefile.in b/src/ibrowse/Makefile.in
-deleted file mode 100644
-index 47581bc..0000000
---- a/src/ibrowse/Makefile.in
-+++ /dev/null
-@@ -1,484 +0,0 @@
--# Makefile.in generated by automake 1.11 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
--# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
--# Inc.
--# This Makefile.in is free software; the Free Software Foundation
--# gives unlimited permission to copy and/or distribute it,
--# with or without modifications, as long as this notice is preserved.
--
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
--# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
--# PARTICULAR PURPOSE.
--
-- at SET_MAKE@
--
--VPATH = @srcdir@
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@PACKAGE@
--am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
--install_sh_DATA = $(install_sh) -c -m 644
--install_sh_PROGRAM = $(install_sh) -c
--install_sh_SCRIPT = $(install_sh) -c
--INSTALL_HEADER = $(INSTALL_DATA)
--transform = $(program_transform_name)
--NORMAL_INSTALL = :
--PRE_INSTALL = :
--POST_INSTALL = :
--NORMAL_UNINSTALL = :
--PRE_UNINSTALL = :
--POST_UNINSTALL = :
--build_triplet = @build@
--host_triplet = @host@
--subdir = src/ibrowse
--DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_curl.m4 \
-- $(top_srcdir)/m4/ac_check_icu.m4 $(top_srcdir)/m4/libtool.m4 \
-- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-- $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-- $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--SOURCES =
--DIST_SOURCES =
--am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
--am__vpath_adj = case $$p in \
-- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-- *) f=$$p;; \
-- esac;
--am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
--am__install_max = 40
--am__nobase_strip_setup = \
-- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
--am__nobase_strip = \
-- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
--am__nobase_list = $(am__nobase_strip_setup); \
-- for p in $$list; do echo "$$p $$p"; done | \
-- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-- if (++n[$$2] == $(am__install_max)) \
-- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-- END { for (dir in files) print dir, files[dir] }'
--am__base_list = \
-- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
--am__installdirs = "$(DESTDIR)$(ibrowseebindir)"
--DATA = $(ibrowseebin_DATA)
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AR = @AR@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CURL_CFLAGS = @CURL_CFLAGS@
--CURL_CONFIG = @CURL_CONFIG@
--CURL_LDFLAGS = @CURL_LDFLAGS@
--CURL_LIBS = @CURL_LIBS@
--CYGPATH_W = @CYGPATH_W@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--ERL = @ERL@
--ERLC = @ERLC@
--ERLC_FLAGS = @ERLC_FLAGS@
--EXEEXT = @EXEEXT@
--FGREP = @FGREP@
--FLAGS = @FLAGS@
--GREP = @GREP@
--HELP2MAN_EXECUTABLE = @HELP2MAN_EXECUTABLE@
--ICU_CFLAGS = @ICU_CFLAGS@
--ICU_CONFIG = @ICU_CONFIG@
--ICU_CXXFLAGS = @ICU_CXXFLAGS@
--ICU_LIBS = @ICU_LIBS@
--ICU_LOCAL_BIN = @ICU_LOCAL_BIN@
--ICU_LOCAL_CFLAGS = @ICU_LOCAL_CFLAGS@
--ICU_LOCAL_LDFLAGS = @ICU_LOCAL_LDFLAGS@
--INNO_COMPILER_EXECUTABLE = @INNO_COMPILER_EXECUTABLE@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--JSLIB = @JSLIB@
--JS_LIB_BASE = @JS_LIB_BASE@
--JS_LIB_BINARY = @JS_LIB_BINARY@
--JS_LIB_DIR = @JS_LIB_DIR@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAKEINFO = @MAKEINFO@
--MKDIR_P = @MKDIR_P@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--RANLIB = @RANLIB@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--VERSION = @VERSION@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--am__include = @am__include@
--am__leading_dot = @am__leading_dot@
--am__quote = @am__quote@
--am__tar = @am__tar@
--am__untar = @am__untar@
--bindir = @bindir@
--bug_uri = @bug_uri@
--build = @build@
--build_alias = @build_alias@
--build_cpu = @build_cpu@
--build_os = @build_os@
--build_vendor = @build_vendor@
--builddir = @builddir@
--datadir = @datadir@
--datarootdir = @datarootdir@
--docdir = @docdir@
--dvidir = @dvidir@
--exec_prefix = @exec_prefix@
--host = @host@
--host_alias = @host_alias@
--host_cpu = @host_cpu@
--host_os = @host_os@
--host_vendor = @host_vendor@
--htmldir = @htmldir@
--includedir = @includedir@
--infodir = @infodir@
--initdir = @initdir@
--install_sh = @install_sh@
--launchddir = @launchddir@
--libdir = @libdir@
--libexecdir = @libexecdir@
--localconfdir = @localconfdir@
--localdatadir = @localdatadir@
--localdocdir = @localdocdir@
--localedir = @localedir@
--localerlanglibdir = @localerlanglibdir@
--locallibbindir = @locallibbindir@
--locallibdir = @locallibdir@
--localstatedir = @localstatedir@
--localstatelibdir = @localstatelibdir@
--localstatelogdir = @localstatelogdir@
--localstaterundir = @localstaterundir@
--lt_ECHO = @lt_ECHO@
--mandir = @mandir@
--mkdir_p = @mkdir_p@
--msvc_redist_dir = @msvc_redist_dir@
--msvc_redist_name = @msvc_redist_name@
--oldincludedir = @oldincludedir@
--openssl_bin_dir = @openssl_bin_dir@
--package_author_address = @package_author_address@
--package_author_name = @package_author_name@
--package_identifier = @package_identifier@
--package_name = @package_name@
--package_tarname = @package_tarname@
--pdfdir = @pdfdir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--version = @version@
--version_major = @version_major@
--version_minor = @version_minor@
--version_release = @version_release@
--version_revision = @version_revision@
--version_stage = @version_stage@
--ibrowseebindir = $(localerlanglibdir)/ibrowse-1.5.2/ebin
--ibrowse_file_collection = \
-- ibrowse.app.in \
-- ibrowse.erl \
-- ibrowse_app.erl \
-- ibrowse_http_client.erl \
-- ibrowse_lb.erl \
-- ibrowse_lib.erl \
-- ibrowse_sup.erl \
-- ibrowse_test.erl
--
--ibrowseebin_make_generated_file_list = \
-- ibrowse.app \
-- ibrowse.beam \
-- ibrowse_app.beam \
-- ibrowse_http_client.beam \
-- ibrowse_lb.beam \
-- ibrowse_lib.beam \
-- ibrowse_sup.beam \
-- ibrowse_test.beam
--
--ibrowseebin_DATA = \
-- $(ibrowseebin_make_generated_file_list)
--
--EXTRA_DIST = \
-- $(ibrowse_file_collection) \
-- ibrowse.hrl
--
--CLEANFILES = \
-- $(ibrowseebin_make_generated_file_list)
--
--all: all-am
--
--.SUFFIXES:
--$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
-- @for dep in $?; do \
-- case '$(am__configure_deps)' in \
-- *$$dep*) \
-- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-- && { if test -f $@; then exit 0; else break; fi; }; \
-- exit 1;; \
-- esac; \
-- done; \
-- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/ibrowse/Makefile'; \
-- $(am__cd) $(top_srcdir) && \
-- $(AUTOMAKE) --foreign src/ibrowse/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-- @case '$?' in \
-- *config.status*) \
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-- *) \
-- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-- esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure: $(am__configure_deps)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4): $(am__aclocal_m4_deps)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--mostlyclean-libtool:
-- -rm -f *.lo
--
--clean-libtool:
-- -rm -rf .libs _libs
--install-ibrowseebinDATA: $(ibrowseebin_DATA)
-- @$(NORMAL_INSTALL)
-- test -z "$(ibrowseebindir)" || $(MKDIR_P) "$(DESTDIR)$(ibrowseebindir)"
-- @list='$(ibrowseebin_DATA)'; test -n "$(ibrowseebindir)" || list=; \
-- for p in $$list; do \
-- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-- echo "$$d$$p"; \
-- done | $(am__base_list) | \
-- while read files; do \
-- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(ibrowseebindir)'"; \
-- $(INSTALL_DATA) $$files "$(DESTDIR)$(ibrowseebindir)" || exit $$?; \
-- done
--
--uninstall-ibrowseebinDATA:
-- @$(NORMAL_UNINSTALL)
-- @list='$(ibrowseebin_DATA)'; test -n "$(ibrowseebindir)" || list=; \
-- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-- test -n "$$files" || exit 0; \
-- echo " ( cd '$(DESTDIR)$(ibrowseebindir)' && rm -f" $$files ")"; \
-- cd "$(DESTDIR)$(ibrowseebindir)" && rm -f $$files
--tags: TAGS
--TAGS:
--
--ctags: CTAGS
--CTAGS:
--
--
--distdir: $(DISTFILES)
-- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-- list='$(DISTFILES)'; \
-- dist_files=`for file in $$list; do echo $$file; done | \
-- sed -e "s|^$$srcdirstrip/||;t" \
-- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-- case $$dist_files in \
-- */*) $(MKDIR_P) `echo "$$dist_files" | \
-- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-- sort -u` ;; \
-- esac; \
-- for file in $$dist_files; do \
-- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-- if test -d $$d/$$file; then \
-- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-- if test -d "$(distdir)/$$file"; then \
-- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-- fi; \
-- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-- fi; \
-- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-- else \
-- test -f "$(distdir)/$$file" \
-- || cp -p $$d/$$file "$(distdir)/$$file" \
-- || exit 1; \
-- fi; \
-- done
--check-am: all-am
--check: check-am
--all-am: Makefile $(DATA)
--installdirs:
-- for dir in "$(DESTDIR)$(ibrowseebindir)"; do \
-- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-- done
--install: install-am
--install-exec: install-exec-am
--install-data: install-data-am
--uninstall: uninstall-am
--
--install-am: all-am
-- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
--
--installcheck: installcheck-am
--install-strip:
-- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-- `test -z '$(STRIP)' || \
-- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
--mostlyclean-generic:
--
--clean-generic:
-- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
--
--distclean-generic:
-- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
-- @echo "This command is intended for maintainers to use"
-- @echo "it deletes files that may require special tools to rebuild."
--clean: clean-am
--
--clean-am: clean-generic clean-libtool mostlyclean-am
--
--distclean: distclean-am
-- -rm -f Makefile
--distclean-am: clean-am distclean-generic
--
--dvi: dvi-am
--
--dvi-am:
--
--html: html-am
--
--html-am:
--
--info: info-am
--
--info-am:
--
--install-data-am: install-ibrowseebinDATA
--
--install-dvi: install-dvi-am
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-am
--
--install-html-am:
--
--install-info: install-info-am
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-am
--
--install-pdf-am:
--
--install-ps: install-ps-am
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-am
-- -rm -f Makefile
--maintainer-clean-am: distclean-am maintainer-clean-generic
--
--mostlyclean: mostlyclean-am
--
--mostlyclean-am: mostlyclean-generic mostlyclean-libtool
--
--pdf: pdf-am
--
--pdf-am:
--
--ps: ps-am
--
--ps-am:
--
--uninstall-am: uninstall-ibrowseebinDATA
--
--.MAKE: install-am install-strip
--
--.PHONY: all all-am check check-am clean clean-generic clean-libtool \
-- distclean distclean-generic distclean-libtool distdir dvi \
-- dvi-am html html-am info info-am install install-am \
-- install-data install-data-am install-dvi install-dvi-am \
-- install-exec install-exec-am install-html install-html-am \
-- install-ibrowseebinDATA install-info install-info-am \
-- install-man install-pdf install-pdf-am install-ps \
-- install-ps-am install-strip installcheck installcheck-am \
-- installdirs maintainer-clean maintainer-clean-generic \
-- mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
-- ps ps-am uninstall uninstall-am uninstall-ibrowseebinDATA
--
--
--%.app: %.app.in
-- cp $< $@
--
--%.beam: %.erl
-- $(ERLC) $(ERLC_FLAGS) $<
--
--# Tell versions [3.59,3.63) of GNU make to not export all variables.
--# Otherwise a system limit (for SysV at least) may be exceeded.
--.NOEXPORT:
diff --git a/src/ibrowse/ibrowse.app.in b/src/ibrowse/ibrowse.app.in
deleted file mode 100644
-index 4f43dd9..0000000
+index c8e4227..0000000
--- a/src/ibrowse/ibrowse.app.in
+++ /dev/null
@@ -1,13 +0,0 @@
-{application, ibrowse,
- [{description, "HTTP client application"},
-- {vsn, "1.5.1"},
-- {modules, [ ibrowse,
-- ibrowse_http_client,
-- ibrowse_app,
-- ibrowse_sup,
+- {vsn, "2.1.2"},
+- {modules, [ ibrowse,
+- ibrowse_http_client,
+- ibrowse_app,
+- ibrowse_sup,
- ibrowse_lib,
- ibrowse_lb ]},
- {registered, []},
@@ -656,10 +128,10 @@ index 4f43dd9..0000000
- {mod, {ibrowse_app, []}}]}.
diff --git a/src/ibrowse/ibrowse.erl b/src/ibrowse/ibrowse.erl
deleted file mode 100644
-index 1913ef5..0000000
+index e105150..0000000
--- a/src/ibrowse/ibrowse.erl
+++ /dev/null
-@@ -1,760 +0,0 @@
+@@ -1,863 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ibrowse.erl
-%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
@@ -668,9 +140,9 @@ index 1913ef5..0000000
-%%% Created : 11 Oct 2003 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%%%-------------------------------------------------------------------
-%% @author Chandrashekhar Mullaparthi <chandrashekhar dot mullaparthi at gmail dot com>
--%% @copyright 2005-2009 Chandrashekhar Mullaparthi
--%% @version 1.5.2
--%% @doc The ibrowse application implements an HTTP 1.1 client. This
+-%% @copyright 2005-2010 Chandrashekhar Mullaparthi
+-%% @version 2.1.2
+-%% @doc The ibrowse application implements an HTTP 1.1 client in erlang. This
-%% module implements the API of the HTTP client. There is one named
-%% process called 'ibrowse' which assists in load balancing and maintaining configuration. There is one load balancing process per unique webserver. There is
-%% one process to handle one TCP connection to a webserver
@@ -683,22 +155,22 @@ index 1913ef5..0000000
-%% <p>Here are a few sample invocations.</p>
-%%
-%% <code>
--%% ibrowse:send_req("http://intranet/messenger/", [], get).
+-%% ibrowse:send_req("http://intranet/messenger/", [], get).
-%% <br/><br/>
--%%
--%% ibrowse:send_req("http://www.google.com/", [], get, [],
--%% [{proxy_user, "XXXXX"},
--%% {proxy_password, "XXXXX"},
--%% {proxy_host, "proxy"},
--%% {proxy_port, 8080}], 1000).
+-%%
+-%% ibrowse:send_req("http://www.google.com/", [], get, [],
+-%% [{proxy_user, "XXXXX"},
+-%% {proxy_password, "XXXXX"},
+-%% {proxy_host, "proxy"},
+-%% {proxy_port, 8080}], 1000).
-%% <br/><br/>
-%%
-%%ibrowse:send_req("http://www.erlang.org/download/otp_src_R10B-3.tar.gz", [], get, [],
--%% [{proxy_user, "XXXXX"},
--%% {proxy_password, "XXXXX"},
--%% {proxy_host, "proxy"},
--%% {proxy_port, 8080},
--%% {save_response_to_file, true}], 1000).
+-%% [{proxy_user, "XXXXX"},
+-%% {proxy_password, "XXXXX"},
+-%% {proxy_host, "proxy"},
+-%% {proxy_port, 8080},
+-%% {save_response_to_file, true}], 1000).
-%% <br/><br/>
-%%
-%% ibrowse:send_req("http://www.erlang.org", [], head).
@@ -710,17 +182,12 @@ index 1913ef5..0000000
-%% ibrowse:send_req("http://www.bbc.co.uk", [], trace).
-%%
-%% <br/><br/>
--%% ibrowse:send_req("http://www.google.com", [], get, [],
+-%% ibrowse:send_req("http://www.google.com", [], get, [],
-%% [{stream_to, self()}]).
-%% </code>
-%%
--%% <p>A driver exists which implements URL encoding in C, but the
--%% speed achieved using only erlang has been good enough, so the
--%% driver isn't actually used.</p>
-
--module(ibrowse).
---vsn('$Id: ibrowse.erl,v 1.8 2009/07/01 22:43:19 chandrusf Exp $ ').
--
--behaviour(gen_server).
-%%--------------------------------------------------------------------
-%% Include files
@@ -732,48 +199,51 @@ index 1913ef5..0000000
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
-- terminate/2, code_change/3]).
+- terminate/2, code_change/3]).
-
-%% API interface
--export([
-- rescan_config/0,
-- rescan_config/1,
-- get_config_value/1,
-- get_config_value/2,
-- spawn_worker_process/2,
-- spawn_link_worker_process/2,
-- stop_worker_process/1,
-- send_req/3,
-- send_req/4,
-- send_req/5,
-- send_req/6,
-- send_req_direct/4,
-- send_req_direct/5,
-- send_req_direct/6,
-- send_req_direct/7,
-- stream_next/1,
-- set_max_sessions/3,
-- set_max_pipeline_size/3,
-- set_dest/3,
-- trace_on/0,
-- trace_off/0,
-- trace_on/2,
-- trace_off/2,
-- all_trace_off/0,
-- show_dest_status/0,
-- show_dest_status/2
-- ]).
+- rescan_config/0,
+- rescan_config/1,
+- get_config_value/1,
+- get_config_value/2,
+- spawn_worker_process/1,
+- spawn_worker_process/2,
+- spawn_link_worker_process/1,
+- spawn_link_worker_process/2,
+- stop_worker_process/1,
+- send_req/3,
+- send_req/4,
+- send_req/5,
+- send_req/6,
+- send_req_direct/4,
+- send_req_direct/5,
+- send_req_direct/6,
+- send_req_direct/7,
+- stream_next/1,
+- stream_close/1,
+- set_max_sessions/3,
+- set_max_pipeline_size/3,
+- set_dest/3,
+- trace_on/0,
+- trace_off/0,
+- trace_on/2,
+- trace_off/2,
+- all_trace_off/0,
+- show_dest_status/0,
+- show_dest_status/2
+- ]).
-
--ifdef(debug).
--compile(export_all).
--endif.
-
--import(ibrowse_lib, [
-- parse_url/1,
-- get_value/3,
-- do_trace/2
-- ]).
--
+- parse_url/1,
+- get_value/3,
+- do_trace/2
+- ]).
+-
--record(state, {trace = false}).
-
--include("ibrowse.hrl").
@@ -821,7 +291,7 @@ index 1913ef5..0000000
-send_req(Url, Headers, Method) ->
- send_req(Url, Headers, Method, [], []).
-
--%% @doc Same as send_req/3.
+-%% @doc Same as send_req/3.
-%% If a list is specified for the body it has to be a flat list. The body can also be a fun/0 or a fun/1. <br/>
-%% If fun/0, the connection handling process will repeatdely call the fun until it returns an error or eof. <pre>Fun() = {ok, Data} | eof</pre><br/>
-%% If fun/1, the connection handling process will repeatedly call the fun with the supplied state until it returns an error or eof. <pre>Fun(State) = {ok, Data} | {ok, Data, NewState} | eof</pre>
@@ -831,19 +301,19 @@ index 1913ef5..0000000
-send_req(Url, Headers, Method, Body) ->
- send_req(Url, Headers, Method, Body, []).
-
--%% @doc Same as send_req/4.
+-%% @doc Same as send_req/4.
-%% For a description of SSL Options, look in the <a href="http://www.erlang.org/doc/apps/ssl/index.html">ssl</a> manpage. If the
-%% HTTP Version to use is not specified, the default is 1.1.
-%% <br/>
--%% <p>The <code>host_header</code> option is useful in the case where ibrowse is
+-%% <ul>
+-%% <li>The <code>host_header</code> option is useful in the case where ibrowse is
-%% connecting to a component such as <a
-%% href="http://www.stunnel.org">stunnel</a> which then sets up a
-%% secure connection to a webserver. In this case, the URL supplied to
-%% ibrowse must have the stunnel host/port details, but that won't
-%% make sense to the destination webserver. This option can then be
-%% used to specify what should go in the <code>Host</code> header in
--%% the request.</p>
--%% <ul>
+-%% the request.</li>
-%% <li>The <code>stream_to</code> option can be used to have the HTTP
-%% response streamed to a process as messages as data arrives on the
-%% socket. If the calling process wishes to control the rate at which
@@ -866,7 +336,11 @@ index 1913ef5..0000000
-%% dealing with large response bodies and/or slow links. In these
-%% cases, it might be hard to estimate how long a request will take to
-%% complete. In such cases, the client might want to timeout if no
--%% data has been received on the link for a certain time interval.</li>
+-%% data has been received on the link for a certain time interval.
+-%%
+-%% This value is also used to close connections which are not in use for
+-%% the specified timeout value.
+-%% </li>
-%%
-%% <li>
-%% The <code>connect_timeout</code> option is to specify how long the
@@ -882,12 +356,30 @@ index 1913ef5..0000000
-%% ibrowse:send_req("http://www.example.com/cgi-bin/request", [], get, [], [{connect_timeout, 100}], 1000).
-%% </code>
-%% In the above invocation, if the connection isn't established within
--%% 100 milliseconds, the request will fail with
+-%% 100 milliseconds, the request will fail with
-%% <code>{error, conn_failed}</code>.<br/>
-%% If connection setup succeeds, the total time allowed for the
-%% request to complete will be 1000 milliseconds minus the time taken
-%% for connection setup.
-%% </li>
+-%%
+-%% <li> The <code>socket_options</code> option can be used to set
+-%% specific options on the socket. The <code>{active, true | false | once}</code>
+-%% and <code>{packet_type, Packet_type}</code> will be filtered out by ibrowse. </li>
+-%%
+-%% <li> The <code>headers_as_is</code> option is to enable the caller
+-%% to send headers exactly as specified in the request without ibrowse
+-%% adding some of its own. Required for some picky servers apparently. </li>
+-%%
+-%% <li>The <code>give_raw_headers</code> option is to enable the
+-%% caller to get access to the raw status line and raw unparsed
+-%% headers. Not quite sure why someone would want this, but one of my
+-%% users asked for it, so here it is. </li>
+-%%
+-%% <li> The <code>preserve_chunked_encoding</code> option enables the caller
+-%% to receive the raw data stream when the Transfer-Encoding of the server
+-%% response is Chunked.
+-%% </li>
-%% </ul>
-%%
-%% @spec send_req(Url::string(), Headers::headerList(), Method::method(), Body::body(), Options::optionList()) -> response()
@@ -896,7 +388,7 @@ index 1913ef5..0000000
-%% {response_format,response_format()}|
-%% {stream_chunk_size, integer()} |
-%% {max_pipeline_size, integer()} |
--%% {trace, boolean()} |
+-%% {trace, boolean()} |
-%% {is_ssl, boolean()} |
-%% {ssl_options, [SSLOpt]} |
-%% {pool_name, atom()} |
@@ -915,13 +407,19 @@ index 1913ef5..0000000
-%% {host_header, string()} |
-%% {inactivity_timeout, integer()} |
-%% {connect_timeout, integer()} |
--%% {transfer_encoding, {chunked, ChunkSize}}
+-%% {socket_options, Sock_opts} |
+-%% {transfer_encoding, {chunked, ChunkSize}} |
+-%% {headers_as_is, boolean()} |
+-%% {give_raw_headers, boolean()} |
+-%% {preserve_chunked_encoding,boolean()}
-%%
-%% stream_to() = process() | {process(), once}
-%% process() = pid() | atom()
-%% username() = string()
-%% password() = string()
-%% SSLOpt = term()
+-%% Sock_opts = [Sock_opt]
+-%% Sock_opt = term()
-%% ChunkSize = integer()
-%% srtf() = boolean() | filename()
-%% filename() = string()
@@ -929,54 +427,76 @@ index 1913ef5..0000000
-send_req(Url, Headers, Method, Body, Options) ->
- send_req(Url, Headers, Method, Body, Options, 30000).
-
--%% @doc Same as send_req/5.
+-%% @doc Same as send_req/5.
-%% All timeout values are in milliseconds.
-%% @spec send_req(Url, Headers::headerList(), Method::method(), Body::body(), Options::optionList(), Timeout) -> response()
-%% Timeout = integer() | infinity
-send_req(Url, Headers, Method, Body, Options, Timeout) ->
- case catch parse_url(Url) of
-- #url{host = Host,
-- port = Port,
-- protocol = Protocol} = Parsed_url ->
-- Lb_pid = case ets:lookup(ibrowse_lb, {Host, Port}) of
-- [] ->
-- get_lb_pid(Parsed_url);
-- [#lb_pid{pid = Lb_pid_1}] ->
-- Lb_pid_1
-- end,
-- Max_sessions = get_max_sessions(Host, Port, Options),
-- Max_pipeline_size = get_max_pipeline_size(Host, Port, Options),
-- Options_1 = merge_options(Host, Port, Options),
-- {SSLOptions, IsSSL} =
-- case (Protocol == https) orelse
-- get_value(is_ssl, Options_1, false) of
-- false -> {[], false};
-- true -> {get_value(ssl_options, Options_1, []), true}
-- end,
-- case ibrowse_lb:spawn_connection(Lb_pid, Parsed_url,
-- Max_sessions,
-- Max_pipeline_size,
-- {SSLOptions, IsSSL}) of
-- {ok, Conn_Pid} ->
-- do_send_req(Conn_Pid, Parsed_url, Headers,
-- Method, Body, Options_1, Timeout);
-- Err ->
-- Err
-- end;
-- Err ->
-- {error, {url_parsing_failed, Err}}
+- #url{host = Host,
+- port = Port,
+- protocol = Protocol} = Parsed_url ->
+- Lb_pid = case ets:lookup(ibrowse_lb, {Host, Port}) of
+- [] ->
+- get_lb_pid(Parsed_url);
+- [#lb_pid{pid = Lb_pid_1}] ->
+- Lb_pid_1
+- end,
+- Max_sessions = get_max_sessions(Host, Port, Options),
+- Max_pipeline_size = get_max_pipeline_size(Host, Port, Options),
+- Options_1 = merge_options(Host, Port, Options),
+- {SSLOptions, IsSSL} =
+- case (Protocol == https) orelse
+- get_value(is_ssl, Options_1, false) of
+- false -> {[], false};
+- true -> {get_value(ssl_options, Options_1, []), true}
+- end,
+- try_routing_request(Lb_pid, Parsed_url,
+- Max_sessions,
+- Max_pipeline_size,
+- {SSLOptions, IsSSL},
+- Headers, Method, Body, Options_1, Timeout, 0);
+- Err ->
+- {error, {url_parsing_failed, Err}}
- end.
-
+-try_routing_request(Lb_pid, Parsed_url,
+- Max_sessions,
+- Max_pipeline_size,
+- {SSLOptions, IsSSL},
+- Headers, Method, Body, Options_1, Timeout, Try_count) when Try_count < 3 ->
+- case ibrowse_lb:spawn_connection(Lb_pid, Parsed_url,
+- Max_sessions,
+- Max_pipeline_size,
+- {SSLOptions, IsSSL}) of
+- {ok, Conn_Pid} ->
+- case do_send_req(Conn_Pid, Parsed_url, Headers,
+- Method, Body, Options_1, Timeout) of
+- {error, sel_conn_closed} ->
+- try_routing_request(Lb_pid, Parsed_url,
+- Max_sessions,
+- Max_pipeline_size,
+- {SSLOptions, IsSSL},
+- Headers, Method, Body, Options_1, Timeout, Try_count + 1);
+- Res ->
+- Res
+- end;
+- Err ->
+- Err
+- end;
+-try_routing_request(_, _, _, _, _, _, _, _, _, _, _) ->
+- {error, retry_later}.
+-
-merge_options(Host, Port, Options) ->
- Config_options = get_config_value({options, Host, Port}, []),
- lists:foldl(
- fun({Key, Val}, Acc) ->
-- case lists:keysearch(Key, 1, Options) of
-- false ->
-- [{Key, Val} | Acc];
-- _ ->
-- Acc
-- end
+- case lists:keysearch(Key, 1, Options) of
+- false ->
+- [{Key, Val} | Acc];
+- _ ->
+- Acc
+- end
- end, Options, Config_options).
-
-get_lb_pid(Url) ->
@@ -984,11 +504,27 @@ index 1913ef5..0000000
-
-get_max_sessions(Host, Port, Options) ->
- get_value(max_sessions, Options,
-- get_config_value({max_sessions, Host, Port}, ?DEF_MAX_SESSIONS)).
+- get_config_value({max_sessions, Host, Port},
+- default_max_sessions())).
-
-get_max_pipeline_size(Host, Port, Options) ->
- get_value(max_pipeline_size, Options,
-- get_config_value({max_pipeline_size, Host, Port}, ?DEF_MAX_PIPELINE_SIZE)).
+- get_config_value({max_pipeline_size, Host, Port},
+- default_max_pipeline_size())).
+-
+-default_max_sessions() ->
+- safe_get_env(ibrowse, default_max_sessions, ?DEF_MAX_SESSIONS).
+-
+-default_max_pipeline_size() ->
+- safe_get_env(ibrowse, default_max_pipeline_size, ?DEF_MAX_PIPELINE_SIZE).
+-
+-safe_get_env(App, Key, Def_val) ->
+- case application:get_env(App, Key) of
+- undefined ->
+- Def_val;
+- {ok, Val} ->
+- Val
+- end.
-
-%% @doc Deprecated. Use set_max_sessions/3 and set_max_pipeline_size/3
-%% for achieving the same effect.
@@ -1005,7 +541,7 @@ index 1913ef5..0000000
- exit({invalid_option, H});
-set_dest(_, _, []) ->
- ok.
--
+-
-%% @doc Set the maximum number of connections allowed to a specific Host:Port.
-%% @spec set_max_sessions(Host::string(), Port::integer(), Max::integer()) -> ok
-set_max_sessions(Host, Port, Max) when is_integer(Max), Max > 0 ->
@@ -1018,21 +554,25 @@ index 1913ef5..0000000
-
-do_send_req(Conn_Pid, Parsed_url, Headers, Method, Body, Options, Timeout) ->
- case catch ibrowse_http_client:send_req(Conn_Pid, Parsed_url,
-- Headers, Method, ensure_bin(Body),
-- Options, Timeout) of
-- {'EXIT', {timeout, _}} ->
-- {error, req_timedout};
-- {'EXIT', Reason} ->
-- {error, {'EXIT', Reason}};
-- {ok, St_code, Headers, Body} = Ret when is_binary(Body) ->
-- case get_value(response_format, Options, list) of
-- list ->
-- {ok, St_code, Headers, binary_to_list(Body)};
-- binary ->
-- Ret
-- end;
-- Ret ->
-- Ret
+- Headers, Method, ensure_bin(Body),
+- Options, Timeout) of
+- {'EXIT', {timeout, _}} ->
+- {error, req_timedout};
+- {'EXIT', {noproc, {gen_server, call, [Conn_Pid, _, _]}}} ->
+- {error, sel_conn_closed};
+- {error, connection_closed} ->
+- {error, sel_conn_closed};
+- {'EXIT', Reason} ->
+- {error, {'EXIT', Reason}};
+- {ok, St_code, Headers, Body} = Ret when is_binary(Body) ->
+- case get_value(response_format, Options, list) of
+- list ->
+- {ok, St_code, Headers, binary_to_list(Body)};
+- binary ->
+- Ret
+- end;
+- Ret ->
+- Ret
- end.
-
-ensure_bin(L) when is_list(L) -> list_to_binary(L);
@@ -1053,12 +593,25 @@ index 1913ef5..0000000
-%% <b>Note:</b> It is the responsibility of the calling process to control
-%% pipeline size on such connections.
-%%
+-%% @spec spawn_worker_process(Url::string()) -> {ok, pid()}
+-spawn_worker_process(Url) ->
+- ibrowse_http_client:start(Url).
+-
+-%% @doc Same as spawn_worker_process/1 but takes as input a Host and Port
+-%% instead of a URL.
-%% @spec spawn_worker_process(Host::string(), Port::integer()) -> {ok, pid()}
-spawn_worker_process(Host, Port) ->
- ibrowse_http_client:start({Host, Port}).
-
+-%% @doc Same as spawn_worker_process/1 except the the calling process
+-%% is linked to the worker process which is spawned.
+-%% @spec spawn_link_worker_process(Url::string()) -> {ok, pid()}
+-spawn_link_worker_process(Url) ->
+- ibrowse_http_client:start_link(Url).
+-
-%% @doc Same as spawn_worker_process/2 except the the calling process
-%% is linked to the worker process which is spawned.
+-%% @spec spawn_link_worker_process(Host::string(), Port::integer()) -> {ok, pid()}
-spawn_link_worker_process(Host, Port) ->
- ibrowse_http_client:start_link({Host, Port}).
-
@@ -1088,30 +641,45 @@ index 1913ef5..0000000
-%% returned by spawn_worker_process/2 or spawn_link_worker_process/2
-send_req_direct(Conn_pid, Url, Headers, Method, Body, Options, Timeout) ->
- case catch parse_url(Url) of
-- #url{host = Host,
-- port = Port} = Parsed_url ->
-- Options_1 = merge_options(Host, Port, Options),
-- case do_send_req(Conn_pid, Parsed_url, Headers, Method, Body, Options_1, Timeout) of
-- {error, {'EXIT', {noproc, _}}} ->
-- {error, worker_is_dead};
-- Ret ->
-- Ret
-- end;
-- Err ->
-- {error, {url_parsing_failed, Err}}
+- #url{host = Host,
+- port = Port} = Parsed_url ->
+- Options_1 = merge_options(Host, Port, Options),
+- case do_send_req(Conn_pid, Parsed_url, Headers, Method, Body, Options_1, Timeout) of
+- {error, {'EXIT', {noproc, _}}} ->
+- {error, worker_is_dead};
+- Ret ->
+- Ret
+- end;
+- Err ->
+- {error, {url_parsing_failed, Err}}
- end.
-
-%% @doc Tell ibrowse to stream the next chunk of data to the
-%% caller. Should be used in conjunction with the
-%% <code>stream_to</code> option
-%% @spec stream_next(Req_id :: req_id()) -> ok | {error, unknown_req_id}
--stream_next(Req_id) ->
+-stream_next(Req_id) ->
- case ets:lookup(ibrowse_stream, {req_id_pid, Req_id}) of
-- [] ->
-- {error, unknown_req_id};
-- [{_, Pid}] ->
-- catch Pid ! {stream_next, Req_id},
-- ok
+- [] ->
+- {error, unknown_req_id};
+- [{_, Pid}] ->
+- catch Pid ! {stream_next, Req_id},
+- ok
+- end.
+-
+-%% @doc Tell ibrowse to close the connection associated with the
+-%% specified stream. Should be used in conjunction with the
+-%% <code>stream_to</code> option. Note that all requests in progress on
+-%% the connection which is serving this Req_id will be aborted, and an
+-%% error returned.
+-%% @spec stream_close(Req_id :: req_id()) -> ok | {error, unknown_req_id}
+-stream_close(Req_id) ->
+- case ets:lookup(ibrowse_stream, {req_id_pid, Req_id}) of
+- [] ->
+- {error, unknown_req_id};
+- [{_, Pid}] ->
+- catch Pid ! {stream_close, Req_id},
+- ok
- end.
-
-%% @doc Turn tracing on for the ibrowse process
@@ -1124,7 +692,7 @@ index 1913ef5..0000000
-%% @doc Turn tracing on for all connections to the specified HTTP
-%% server. Host is whatever is specified as the domain name in the URL
-%% @spec trace_on(Host, Port) -> ok
--%% Host = string()
+-%% Host = string()
-%% Port = integer()
-trace_on(Host, Port) ->
- ibrowse ! {trace, true, Host, Port},
@@ -1143,77 +711,80 @@ index 1913ef5..0000000
- ibrowse ! all_trace_off,
- ok.
-
+-%% @doc Shows some internal information about load balancing. Info
+-%% about workers spawned using spawn_worker_process/2 or
+-%% spawn_link_worker_process/2 is not included.
-show_dest_status() ->
- Dests = lists:filter(fun({lb_pid, {Host, Port}, _}) when is_list(Host),
-- is_integer(Port) ->
-- true;
-- (_) ->
-- false
-- end, ets:tab2list(ibrowse_lb)),
+- is_integer(Port) ->
+- true;
+- (_) ->
+- false
+- end, ets:tab2list(ibrowse_lb)),
- All_ets = ets:all(),
- io:format("~-40.40s | ~-5.5s | ~-10.10s | ~s~n",
-- ["Server:port", "ETS", "Num conns", "LB Pid"]),
+- ["Server:port", "ETS", "Num conns", "LB Pid"]),
- io:format("~80.80.=s~n", [""]),
- lists:foreach(fun({lb_pid, {Host, Port}, Lb_pid}) ->
-- case lists:dropwhile(
-- fun(Tid) ->
-- ets:info(Tid, owner) /= Lb_pid
-- end, All_ets) of
-- [] ->
-- io:format("~40.40s | ~-5.5s | ~-5.5s | ~s~n",
-- [Host ++ ":" ++ integer_to_list(Port),
-- "",
-- "",
-- io_lib:format("~p", [Lb_pid])]
-- );
-- [Tid | _] ->
-- catch (
-- begin
-- Size = ets:info(Tid, size),
-- io:format("~40.40s | ~-5.5s | ~-5.5s | ~s~n",
-- [Host ++ ":" ++ integer_to_list(Port),
-- integer_to_list(Tid),
-- integer_to_list(Size),
-- io_lib:format("~p", [Lb_pid])]
-- )
-- end
-- )
-- end
-- end, Dests).
--
+- case lists:dropwhile(
+- fun(Tid) ->
+- ets:info(Tid, owner) /= Lb_pid
+- end, All_ets) of
+- [] ->
+- io:format("~40.40s | ~-5.5s | ~-5.5s | ~s~n",
+- [Host ++ ":" ++ integer_to_list(Port),
+- "",
+- "",
+- io_lib:format("~p", [Lb_pid])]
+- );
+- [Tid | _] ->
+- catch (
+- begin
+- Size = ets:info(Tid, size),
+- io:format("~40.40s | ~-5.5s | ~-5.5s | ~s~n",
+- [Host ++ ":" ++ integer_to_list(Port),
+- io_lib:format("~p", [Tid]),
+- integer_to_list(Size),
+- io_lib:format("~p", [Lb_pid])]
+- )
+- end
+- )
+- end
+- end, Dests).
+-
-%% @doc Shows some internal information about load balancing to a
-%% specified Host:Port. Info about workers spawned using
-%% spawn_worker_process/2 or spawn_link_worker_process/2 is not
-%% included.
-show_dest_status(Host, Port) ->
- case ets:lookup(ibrowse_lb, {Host, Port}) of
-- [] ->
-- no_active_processes;
-- [#lb_pid{pid = Lb_pid}] ->
-- io:format("Load Balancer Pid : ~p~n", [Lb_pid]),
-- io:format("LB process msg q size : ~p~n", [(catch process_info(Lb_pid, message_queue_len))]),
-- case lists:dropwhile(
-- fun(Tid) ->
-- ets:info(Tid, owner) /= Lb_pid
-- end, ets:all()) of
-- [] ->
-- io:format("Couldn't locate ETS table for ~p~n", [Lb_pid]);
-- [Tid | _] ->
-- First = ets:first(Tid),
-- Last = ets:last(Tid),
-- Size = ets:info(Tid, size),
-- io:format("LB ETS table id : ~p~n", [Tid]),
-- io:format("Num Connections : ~p~n", [Size]),
-- case Size of
-- 0 ->
-- ok;
-- _ ->
-- {First_p_sz, _} = First,
-- {Last_p_sz, _} = Last,
-- io:format("Smallest pipeline : ~1000.p~n", [First_p_sz]),
-- io:format("Largest pipeline : ~1000.p~n", [Last_p_sz])
-- end
-- end
+- [] ->
+- no_active_processes;
+- [#lb_pid{pid = Lb_pid}] ->
+- io:format("Load Balancer Pid : ~p~n", [Lb_pid]),
+- io:format("LB process msg q size : ~p~n", [(catch process_info(Lb_pid, message_queue_len))]),
+- case lists:dropwhile(
+- fun(Tid) ->
+- ets:info(Tid, owner) /= Lb_pid
+- end, ets:all()) of
+- [] ->
+- io:format("Couldn't locate ETS table for ~p~n", [Lb_pid]);
+- [Tid | _] ->
+- First = ets:first(Tid),
+- Last = ets:last(Tid),
+- Size = ets:info(Tid, size),
+- io:format("LB ETS table id : ~p~n", [Tid]),
+- io:format("Num Connections : ~p~n", [Size]),
+- case Size of
+- 0 ->
+- ok;
+- _ ->
+- {First_p_sz, _} = First,
+- {Last_p_sz, _} = Last,
+- io:format("Smallest pipeline : ~1000.p~n", [First_p_sz]),
+- io:format("Largest pipeline : ~1000.p~n", [Last_p_sz])
+- end
+- end
- end.
-
-%% @doc Clear current configuration for ibrowse and load from the file
@@ -1254,40 +825,40 @@ index 1913ef5..0000000
-
-import_config() ->
- case code:priv_dir(ibrowse) of
-- {error, _} = Err ->
-- Err;
-- PrivDir ->
-- Filename = filename:join(PrivDir, "ibrowse.conf"),
-- import_config(Filename)
+- {error, _} = Err ->
+- Err;
+- PrivDir ->
+- Filename = filename:join(PrivDir, "ibrowse.conf"),
+- import_config(Filename)
- end.
-
-import_config(Filename) ->
- case file:consult(Filename) of
-- {ok, Terms} ->
-- ets:delete_all_objects(ibrowse_conf),
-- Fun = fun({dest, Host, Port, MaxSess, MaxPipe, Options})
-- when is_list(Host), is_integer(Port),
-- is_integer(MaxSess), MaxSess > 0,
-- is_integer(MaxPipe), MaxPipe > 0, is_list(Options) ->
-- I = [{{max_sessions, Host, Port}, MaxSess},
-- {{max_pipeline_size, Host, Port}, MaxPipe},
-- {{options, Host, Port}, Options}],
-- lists:foreach(
-- fun({X, Y}) ->
-- ets:insert(ibrowse_conf,
-- #ibrowse_conf{key = X,
-- value = Y})
-- end, I);
-- ({K, V}) ->
-- ets:insert(ibrowse_conf,
-- #ibrowse_conf{key = K,
-- value = V});
-- (X) ->
-- io:format("Skipping unrecognised term: ~p~n", [X])
-- end,
-- lists:foreach(Fun, Terms);
-- Err ->
-- Err
+- {ok, Terms} ->
+- ets:delete_all_objects(ibrowse_conf),
+- Fun = fun({dest, Host, Port, MaxSess, MaxPipe, Options})
+- when is_list(Host), is_integer(Port),
+- is_integer(MaxSess), MaxSess > 0,
+- is_integer(MaxPipe), MaxPipe > 0, is_list(Options) ->
+- I = [{{max_sessions, Host, Port}, MaxSess},
+- {{max_pipeline_size, Host, Port}, MaxPipe},
+- {{options, Host, Port}, Options}],
+- lists:foreach(
+- fun({X, Y}) ->
+- ets:insert(ibrowse_conf,
+- #ibrowse_conf{key = X,
+- value = Y})
+- end, I);
+- ({K, V}) ->
+- ets:insert(ibrowse_conf,
+- #ibrowse_conf{key = K,
+- value = V});
+- (X) ->
+- io:format("Skipping unrecognised term: ~p~n", [X])
+- end,
+- lists:foreach(Fun, Terms);
+- Err ->
+- Err
- end.
-
-%% @doc Internal export
@@ -1298,10 +869,10 @@ index 1913ef5..0000000
-%% @doc Internal export
-get_config_value(Key, DefVal) ->
- case ets:lookup(ibrowse_conf, Key) of
-- [] ->
-- DefVal;
-- [#ibrowse_conf{value = V}] ->
-- V
+- [] ->
+- DefVal;
+- [#ibrowse_conf{value = V}] ->
+- V
- end.
-
-set_config_value(Key, Val) ->
@@ -1322,6 +893,10 @@ index 1913ef5..0000000
-
-handle_call(stop, _From, State) ->
- do_trace("IBROWSE shutting down~n", []),
+- ets:foldl(fun(#lb_pid{pid = Pid}, Acc) ->
+- ibrowse_lb:stop(Pid),
+- Acc
+- end, [], ibrowse_lb),
- {stop, normal, ok, State};
-
-handle_call({set_config_value, Key, Val}, _From, State) ->
@@ -1362,36 +937,36 @@ index 1913ef5..0000000
- Mspec = [{{ibrowse_conf,{trace,'$1','$2'},true},[],[{{'$1','$2'}}]}],
- Trace_on_dests = ets:select(ibrowse_conf, Mspec),
- Fun = fun(#lb_pid{host_port = {H, P}, pid = Pid}, _) ->
-- case lists:member({H, P}, Trace_on_dests) of
-- false ->
-- ok;
-- true ->
-- catch Pid ! {trace, false}
-- end;
-- (_, Acc) ->
-- Acc
-- end,
+- case lists:member({H, P}, Trace_on_dests) of
+- false ->
+- ok;
+- true ->
+- catch Pid ! {trace, false}
+- end;
+- (_, Acc) ->
+- Acc
+- end,
- ets:foldl(Fun, undefined, ibrowse_lb),
- ets:select_delete(ibrowse_conf, [{{ibrowse_conf,{trace,'$1','$2'},true},[],['true']}]),
- {noreply, State};
--
+-
-handle_info({trace, Bool}, State) ->
- put(my_trace_flag, Bool),
- {noreply, State};
-
-handle_info({trace, Bool, Host, Port}, State) ->
- Fun = fun(#lb_pid{host_port = {H, P}, pid = Pid}, _)
-- when H == Host,
-- P == Port ->
-- catch Pid ! {trace, Bool};
-- (_, Acc) ->
-- Acc
-- end,
+- when H == Host,
+- P == Port ->
+- catch Pid ! {trace, Bool};
+- (_, Acc) ->
+- Acc
+- end,
- ets:foldl(Fun, undefined, ibrowse_lb),
- ets:insert(ibrowse_conf, #ibrowse_conf{key = {trace, Host, Port},
-- value = Bool}),
+- value = Bool}),
- {noreply, State};
--
+-
-handle_info(_Info, State) ->
- {noreply, State}.
-
@@ -1440,19 +1015,18 @@ index ebf3bb3..0000000
--endif.
diff --git a/src/ibrowse/ibrowse_app.erl b/src/ibrowse/ibrowse_app.erl
deleted file mode 100644
-index 8c83e8f..0000000
+index d3a0f7b..0000000
--- a/src/ibrowse/ibrowse_app.erl
+++ /dev/null
-@@ -1,64 +0,0 @@
+@@ -1,63 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ibrowse_app.erl
-%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
--%%% Description :
+-%%% Description :
-%%%
-%%% Created : 15 Oct 2003 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%%%-------------------------------------------------------------------
--module(ibrowse_app).
---vsn('$Id: ibrowse_app.erl,v 1.1 2005/05/05 22:28:28 chandrusf Exp $ ').
-
--behaviour(application).
-%%--------------------------------------------------------------------
@@ -1488,11 +1062,11 @@ index 8c83e8f..0000000
-%% Func: start/2
-%% Returns: {ok, Pid} |
-%% {ok, Pid, State} |
--%% {error, Reason}
+-%% {error, Reason}
-%%--------------------------------------------------------------------
-start(_Type, _StartArgs) ->
- case ibrowse_sup:start_link() of
-- {ok, Pid} ->
+- {ok, Pid} ->
- {ok, Pid};
- Error ->
- Error
@@ -1500,7 +1074,7 @@ index 8c83e8f..0000000
-
-%%--------------------------------------------------------------------
-%% Func: stop/1
--%% Returns: any
+-%% Returns: any
-%%--------------------------------------------------------------------
-stop(_State) ->
- ok.
@@ -1510,10 +1084,10 @@ index 8c83e8f..0000000
-%%====================================================================
diff --git a/src/ibrowse/ibrowse_http_client.erl b/src/ibrowse/ibrowse_http_client.erl
deleted file mode 100644
-index 65d9cb9..0000000
+index 5dce321..0000000
--- a/src/ibrowse/ibrowse_http_client.erl
+++ /dev/null
-@@ -1,1476 +0,0 @@
+@@ -1,1821 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ibrowse_http_client.erl
-%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
@@ -1522,8 +1096,6 @@ index 65d9cb9..0000000
-%%% Created : 11 Oct 2003 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%%%-------------------------------------------------------------------
--module(ibrowse_http_client).
---vsn('$Id: ibrowse_http_client.erl,v 1.19 2009/07/01 22:43:19 chandrusf Exp $ ').
--
--behaviour(gen_server).
-%%--------------------------------------------------------------------
-%% Include files
@@ -1532,11 +1104,11 @@ index 65d9cb9..0000000
-%%--------------------------------------------------------------------
-%% External exports
--export([
-- start_link/1,
-- start/1,
-- stop/1,
-- send_req/7
-- ]).
+- start_link/1,
+- start/1,
+- stop/1,
+- send_req/7
+- ]).
-
--ifdef(debug).
--compile(export_all).
@@ -1544,44 +1116,50 @@ index 65d9cb9..0000000
-
-%% gen_server callbacks
--export([
-- init/1,
-- handle_call/3,
-- handle_cast/2,
-- handle_info/2,
-- terminate/2,
-- code_change/3
-- ]).
+- init/1,
+- handle_call/3,
+- handle_cast/2,
+- handle_info/2,
+- terminate/2,
+- code_change/3
+- ]).
-
--include("ibrowse.hrl").
-
---record(state, {host, port,
-- use_proxy = false, proxy_auth_digest,
-- ssl_options = [], is_ssl = false, socket,
-- reqs=queue:new(), cur_req, status=idle, http_status_code,
-- reply_buffer = <<>>, rep_buf_size=0, streamed_size = 0,
-- recvd_headers=[],
-- is_closing, send_timer, content_length,
-- deleted_crlf = false, transfer_encoding,
-- chunk_size, chunk_size_buffer = <<>>, recvd_chunk_size,
-- lb_ets_tid, cur_pipeline_size = 0, prev_req_id
-- }).
+--record(state, {host, port, connect_timeout,
+- inactivity_timer_ref,
+- use_proxy = false, proxy_auth_digest,
+- ssl_options = [], is_ssl = false, socket,
+- proxy_tunnel_setup = false,
+- tunnel_setup_queue = [],
+- reqs=queue:new(), cur_req, status=idle, http_status_code,
+- reply_buffer = <<>>, rep_buf_size=0, streamed_size = 0,
+- recvd_headers=[],
+- status_line, raw_headers,
+- is_closing, send_timer, content_length,
+- deleted_crlf = false, transfer_encoding,
+- chunk_size, chunk_size_buffer = <<>>,
+- recvd_chunk_size, interim_reply_sent = false,
+- lb_ets_tid, cur_pipeline_size = 0, prev_req_id
+- }).
-
--record(request, {url, method, options, from,
-- stream_to, caller_controls_socket = false,
-- req_id,
-- stream_chunk_size,
-- save_response_to_file = false,
-- tmp_file_name, tmp_file_fd,
-- response_format}).
+- stream_to, caller_controls_socket = false,
+- caller_socket_options = [],
+- req_id,
+- stream_chunk_size,
+- save_response_to_file = false,
+- tmp_file_name, tmp_file_fd, preserve_chunked_encoding,
+- response_format}).
-
--import(ibrowse_lib, [
-- get_value/2,
-- get_value/3,
-- do_trace/2
-- ]).
+- get_value/2,
+- get_value/3,
+- do_trace/2
+- ]).
-
--define(DEFAULT_STREAM_CHUNK_SIZE, 1024*1024).
--
+--define(dec2hex(X), erlang:integer_to_list(X, 16)).
-%%====================================================================
-%% External functions
-%%====================================================================
@@ -1596,7 +1174,13 @@ index 65d9cb9..0000000
- gen_server:start_link(?MODULE, Args, []).
-
-stop(Conn_pid) ->
-- gen_server:call(Conn_pid, stop).
+- case catch gen_server:call(Conn_pid, stop) of
+- {'EXIT', {timeout, _}} ->
+- exit(Conn_pid, kill),
+- ok;
+- _ ->
+- ok
+- end.
-
-send_req(Conn_Pid, Url, Headers, Method, Body, Options, Timeout) ->
- gen_server:call(
@@ -1617,26 +1201,23 @@ index 65d9cb9..0000000
-%%--------------------------------------------------------------------
-init({Lb_Tid, #url{host = Host, port = Port}, {SSLOptions, Is_ssl}}) ->
- State = #state{host = Host,
-- port = Port,
-- ssl_options = SSLOptions,
-- is_ssl = Is_ssl,
-- lb_ets_tid = Lb_Tid},
+- port = Port,
+- ssl_options = SSLOptions,
+- is_ssl = Is_ssl,
+- lb_ets_tid = Lb_Tid},
- put(ibrowse_trace_token, [Host, $:, integer_to_list(Port)]),
- put(my_trace_flag, ibrowse_lib:get_trace_status(Host, Port)),
- {ok, State};
+-init(Url) when is_list(Url) ->
+- case catch ibrowse_lib:parse_url(Url) of
+- #url{protocol = Protocol} = Url_rec ->
+- init({undefined, Url_rec, {[], Protocol == https}});
+- {'EXIT', _} ->
+- {error, invalid_url}
+- end;
-init({Host, Port}) ->
- State = #state{host = Host,
-- port = Port},
-- put(ibrowse_trace_token, [Host, $:, integer_to_list(Port)]),
-- put(my_trace_flag, ibrowse_lib:get_trace_status(Host, Port)),
-- {ok, State};
--init(#url{host=Host, port=Port, protocol=Protocol}) ->
-- State = #state{
-- host = Host,
-- port = Port,
-- is_ssl = (Protocol == https),
-- ssl_options = [{ssl_imp, new}, {depth, 9}]
-- },
+- port = Port},
- put(ibrowse_trace_token, [Host, $:, integer_to_list(Port)]),
- put(my_trace_flag, ibrowse_lib:get_trace_status(Host, Port)),
- {ok, State}.
@@ -1657,13 +1238,13 @@ index 65d9cb9..0000000
- {reply, {error, connection_closing}, State};
-
-handle_call({send_req, {Url, Headers, Method, Body, Options, Timeout}},
-- From, State) ->
+- From, State) ->
- send_req_1(From, Url, Headers, Method, Body, Options, Timeout, State);
-
-handle_call(stop, _From, State) ->
- do_close(State),
- do_error_reply(State, closing_on_request),
-- {stop, normal, ok, State#state{socket=undefined}};
+- {stop, normal, ok, State};
-
-handle_call(Request, _From, State) ->
- Reply = {unknown_request, Request},
@@ -1687,21 +1268,36 @@ index 65d9cb9..0000000
-%% {stop, Reason, State} (terminate/2 is called)
-%%--------------------------------------------------------------------
-handle_info({tcp, _Sock, Data}, #state{status = Status} = State) ->
+-%% io:format("Recvd data: ~p~n", [Data]),
- do_trace("Data recvd in state: ~p. Size: ~p. ~p~n~n", [Status, size(Data), Data]),
- handle_sock_data(Data, State);
-handle_info({ssl, _Sock, Data}, State) ->
- handle_sock_data(Data, State);
-
-handle_info({stream_next, Req_id}, #state{socket = Socket,
-- is_ssl = Is_ssl,
-- cur_req = #request{req_id = Req_id}} = State) ->
-- do_setopts(Socket, [{active, once}], Is_ssl),
+- cur_req = #request{req_id = Req_id}} = State) ->
+- %% io:format("Client process set {active, once}~n", []),
+- do_setopts(Socket, [{active, once}], State),
- {noreply, State};
-
-handle_info({stream_next, _Req_id}, State) ->
+- _Cur_req_id = case State#state.cur_req of
+- #request{req_id = Cur} ->
+- Cur;
+- _ ->
+- undefined
+- end,
+-%% io:format("Ignoring stream_next as ~1000.p is not cur req (~1000.p)~n",
+-%% [_Req_id, _Cur_req_id]),
- {noreply, State};
-
--handle_info({tcp_closed, _Sock}, State) ->
+-handle_info({stream_close, _Req_id}, State) ->
+- shutting_down(State),
+- do_close(State),
+- do_error_reply(State, closing_on_request),
+- {stop, normal, State};
+-
+-handle_info({tcp_closed, _Sock}, State) ->
- do_trace("TCP connection closed by peer!~n", []),
- handle_sock_closed(State),
- {stop, normal, State};
@@ -1711,25 +1307,26 @@ index 65d9cb9..0000000
- {stop, normal, State};
-
-handle_info({tcp_error, _Sock}, State) ->
-- io:format("Error on connection to ~1000.p:~1000.p~n", [State#state.host, State#state.port]),
+- do_trace("Error on connection to ~1000.p:~1000.p~n", [State#state.host, State#state.port]),
- handle_sock_closed(State),
- {stop, normal, State};
-handle_info({ssl_error, _Sock}, State) ->
-- io:format("Error on SSL connection to ~1000.p:~1000.p~n", [State#state.host, State#state.port]),
+- do_trace("Error on SSL connection to ~1000.p:~1000.p~n", [State#state.host, State#state.port]),
- handle_sock_closed(State),
- {stop, normal, State};
-
-handle_info({req_timedout, From}, State) ->
-- case lists:keysearch(From, #request.from, queue:to_list(State#state.reqs)) of
-- false ->
-- {noreply, State};
-- {value, _} ->
-- shutting_down(State),
-- do_error_reply(State, req_timedout),
-- {stop, normal, State}
+- case lists:keymember(From, #request.from, queue:to_list(State#state.reqs)) of
+- false ->
+- {noreply, State};
+- true ->
+- shutting_down(State),
+- do_error_reply(State, req_timedout),
+- {stop, normal, State}
- end;
-
-handle_info(timeout, State) ->
+- do_trace("Inactivity timeout triggered. Shutting down connection~n", []),
- shutting_down(State),
- do_error_reply(State, req_timedout),
- {stop, normal, State};
@@ -1740,7 +1337,7 @@ index 65d9cb9..0000000
-
-handle_info(Info, State) ->
- io:format("Unknown message recvd for ~1000.p:~1000.p -> ~p~n",
-- [State#state.host, State#state.port, Info]),
+- [State#state.host, State#state.port, Info]),
- io:format("Recvd unknown message ~p when in state: ~p~n", [Info, State]),
- {noreply, State}.
-
@@ -1750,7 +1347,8 @@ index 65d9cb9..0000000
-%% Returns: any (ignored by gen_server)
-%%--------------------------------------------------------------------
-terminate(_Reason, State) ->
-- do_close(State).
+- do_close(State),
+- ok.
-
-%%--------------------------------------------------------------------
-%% Func: code_change/3
@@ -1776,133 +1374,155 @@ index 65d9cb9..0000000
-
-handle_sock_data(Data, #state{status = get_header}=State) ->
- case parse_response(Data, State) of
-- {error, _Reason} ->
-- shutting_down(State),
-- {stop, normal, State};
-- stop ->
-- shutting_down(State),
-- {stop, normal, State};
-- State_1 ->
-- active_once(State_1),
-- {noreply, State_1, get_inac_timeout(State_1)}
+- {error, _Reason} ->
+- shutting_down(State),
+- {stop, normal, State};
+- #state{socket = Socket, status = Status, cur_req = CurReq} = State_1 ->
+- case {Status, CurReq} of
+- {get_header, #request{caller_controls_socket = true}} ->
+- do_setopts(Socket, [{active, once}], State_1);
+- _ ->
+- active_once(State_1)
+- end,
+- {noreply, set_inac_timer(State_1)}
- end;
-
-handle_sock_data(Data, #state{status = get_body,
-- content_length = CL,
-- http_status_code = StatCode,
-- recvd_headers = Headers,
-- chunk_size = CSz} = State) ->
+- socket = Socket,
+- content_length = CL,
+- http_status_code = StatCode,
+- recvd_headers = Headers,
+- chunk_size = CSz} = State) ->
- case (CL == undefined) and (CSz == undefined) of
-- true ->
-- case accumulate_response(Data, State) of
-- {error, Reason} ->
-- shutting_down(State),
-- fail_pipelined_requests(State,
-- {error, {Reason, {stat_code, StatCode}, Headers}}),
-- {stop, normal, State};
-- State_1 ->
-- active_once(State_1),
-- {noreply, State_1, get_inac_timeout(State_1)}
-- end;
-- _ ->
-- case parse_11_response(Data, State) of
-- {error, Reason} ->
-- shutting_down(State),
-- fail_pipelined_requests(State,
-- {error, {Reason, {stat_code, StatCode}, Headers}}),
-- {stop, normal, State};
-- stop ->
-- shutting_down(State),
-- {stop, normal, State};
-- State_1 ->
-- active_once(State_1),
-- {noreply, State_1, get_inac_timeout(State_1)}
-- end
+- true ->
+- case accumulate_response(Data, State) of
+- {error, Reason} ->
+- shutting_down(State),
+- fail_pipelined_requests(State,
+- {error, {Reason, {stat_code, StatCode}, Headers}}),
+- {stop, normal, State};
+- State_1 ->
+- active_once(State_1),
+- State_2 = set_inac_timer(State_1),
+- {noreply, State_2}
+- end;
+- _ ->
+- case parse_11_response(Data, State) of
+- {error, Reason} ->
+- shutting_down(State),
+- fail_pipelined_requests(State,
+- {error, {Reason, {stat_code, StatCode}, Headers}}),
+- {stop, normal, State};
+- #state{cur_req = #request{caller_controls_socket = Ccs},
+- interim_reply_sent = Irs} = State_1 ->
+- case Irs of
+- true ->
+- active_once(State_1);
+- false when Ccs == true ->
+- do_setopts(Socket, [{active, once}], State);
+- false ->
+- active_once(State_1)
+- end,
+- State_2 = State_1#state{interim_reply_sent = false},
+- State_3 = set_inac_timer(State_2),
+- {noreply, State_3};
+- State_1 ->
+- active_once(State_1),
+- State_2 = set_inac_timer(State_1),
+- {noreply, State_2}
+- end
- end.
-
-accumulate_response(Data,
-- #state{
-- cur_req = #request{save_response_to_file = true,
-- tmp_file_fd = undefined} = CurReq,
-- http_status_code=[$2 | _]}=State) ->
-- TmpFilename = make_tmp_filename(),
+- #state{
+- cur_req = #request{save_response_to_file = Srtf,
+- tmp_file_fd = undefined} = CurReq,
+- http_status_code=[$2 | _]}=State) when Srtf /= false ->
+- TmpFilename = make_tmp_filename(Srtf),
- case file:open(TmpFilename, [write, delayed_write, raw]) of
-- {ok, Fd} ->
-- accumulate_response(Data, State#state{
-- cur_req = CurReq#request{
-- tmp_file_fd = Fd,
-- tmp_file_name = TmpFilename}});
-- {error, Reason} ->
-- {error, {file_open_error, Reason}}
+- {ok, Fd} ->
+- accumulate_response(Data, State#state{
+- cur_req = CurReq#request{
+- tmp_file_fd = Fd,
+- tmp_file_name = TmpFilename}});
+- {error, Reason} ->
+- {error, {file_open_error, Reason}}
- end;
--accumulate_response(Data, #state{cur_req = #request{save_response_to_file = true,
-- tmp_file_fd = Fd},
-- transfer_encoding=chunked,
-- reply_buffer = Reply_buf,
-- http_status_code=[$2 | _]
-- } = State) ->
+-accumulate_response(Data, #state{cur_req = #request{save_response_to_file = Srtf,
+- tmp_file_fd = Fd},
+- transfer_encoding=chunked,
+- reply_buffer = Reply_buf,
+- http_status_code=[$2 | _]
+- } = State) when Srtf /= false ->
- case file:write(Fd, [Reply_buf, Data]) of
-- ok ->
-- State#state{reply_buffer = <<>>};
-- {error, Reason} ->
-- {error, {file_write_error, Reason}}
+- ok ->
+- State#state{reply_buffer = <<>>};
+- {error, Reason} ->
+- {error, {file_write_error, Reason}}
- end;
--accumulate_response(Data, #state{cur_req = #request{save_response_to_file = true,
-- tmp_file_fd = Fd},
-- reply_buffer = RepBuf,
-- http_status_code=[$2 | _]
-- } = State) ->
+-accumulate_response(Data, #state{cur_req = #request{save_response_to_file = Srtf,
+- tmp_file_fd = Fd},
+- reply_buffer = RepBuf,
+- http_status_code=[$2 | _]
+- } = State) when Srtf /= false ->
- case file:write(Fd, [RepBuf, Data]) of
-- ok ->
-- State#state{reply_buffer = <<>>};
-- {error, Reason} ->
-- {error, {file_write_error, Reason}}
+- ok ->
+- State#state{reply_buffer = <<>>};
+- {error, Reason} ->
+- {error, {file_write_error, Reason}}
- end;
--accumulate_response(<<>>, State) ->
-- State;
--accumulate_response(Data, #state{reply_buffer = RepBuf,
-- rep_buf_size = RepBufSize,
-- streamed_size = Streamed_size,
-- cur_req = CurReq}=State) ->
-- #request{stream_to=StreamTo, req_id=ReqId,
-- stream_chunk_size = Stream_chunk_size,
-- response_format = Response_format,
-- caller_controls_socket = Caller_controls_socket} = CurReq,
-- RepBuf_1 = list_to_binary([RepBuf, Data]),
+-accumulate_response(Data, #state{reply_buffer = RepBuf,
+- rep_buf_size = RepBufSize,
+- streamed_size = Streamed_size,
+- cur_req = CurReq}=State) ->
+- #request{stream_to = StreamTo,
+- req_id = ReqId,
+- stream_chunk_size = Stream_chunk_size,
+- response_format = Response_format,
+- caller_controls_socket = Caller_controls_socket} = CurReq,
+- RepBuf_1 = <<RepBuf/binary, Data/binary>>,
- New_data_size = RepBufSize - Streamed_size,
- case StreamTo of
-- undefined ->
-- State#state{reply_buffer = RepBuf_1};
-- _ when Caller_controls_socket == true ->
-- do_interim_reply(StreamTo, Response_format, ReqId, RepBuf_1),
-- State#state{reply_buffer = <<>>,
-- streamed_size = Streamed_size + size(RepBuf_1)};
-- _ when New_data_size >= Stream_chunk_size ->
-- {Stream_chunk, Rem_data} = split_binary(RepBuf_1, Stream_chunk_size),
-- do_interim_reply(StreamTo, Response_format, ReqId, Stream_chunk),
-- accumulate_response(
-- Rem_data,
-- State#state{
-- reply_buffer = <<>>,
-- streamed_size = Streamed_size + Stream_chunk_size});
-- _ ->
-- State#state{reply_buffer = RepBuf_1}
+- undefined ->
+- State#state{reply_buffer = RepBuf_1};
+- _ when Caller_controls_socket == true ->
+- do_interim_reply(StreamTo, Response_format, ReqId, RepBuf_1),
+- State#state{reply_buffer = <<>>,
+- interim_reply_sent = true,
+- streamed_size = Streamed_size + size(RepBuf_1)};
+- _ when New_data_size >= Stream_chunk_size ->
+- {Stream_chunk, Rem_data} = split_binary(RepBuf_1, Stream_chunk_size),
+- do_interim_reply(StreamTo, Response_format, ReqId, Stream_chunk),
+- State_1 = State#state{
+- reply_buffer = <<>>,
+- interim_reply_sent = true,
+- streamed_size = Streamed_size + Stream_chunk_size},
+- case Rem_data of
+- <<>> ->
+- State_1;
+- _ ->
+- accumulate_response(Rem_data, State_1)
+- end;
+- _ ->
+- State#state{reply_buffer = RepBuf_1}
- end.
-
--make_tmp_filename() ->
+-make_tmp_filename(true) ->
- DownloadDir = ibrowse:get_config_value(download_dir, filename:absname("./")),
- {A,B,C} = now(),
- filename:join([DownloadDir,
-- "ibrowse_tmp_file_"++
-- integer_to_list(A) ++
-- integer_to_list(B) ++
-- integer_to_list(C)]).
+- "ibrowse_tmp_file_"++
+- integer_to_list(A) ++
+- integer_to_list(B) ++
+- integer_to_list(C)]);
+-make_tmp_filename(File) when is_list(File) ->
+- File.
-
-
-%%--------------------------------------------------------------------
-%% Handles the case when the server closes the socket
-%%--------------------------------------------------------------------
--handle_sock_closed(#state{status=get_header}=State) ->
+-handle_sock_closed(#state{status=get_header} = State) ->
- shutting_down(State),
- do_error_reply(State, connection_closed);
-
@@ -1913,40 +1533,73 @@ index 65d9cb9..0000000
-%% Connection-Close header and has closed the socket to indicate end
-%% of response. There maybe requests pipelined which need a response.
-handle_sock_closed(#state{reply_buffer = Buf, reqs = Reqs, http_status_code = SC,
-- is_closing = IsClosing,
-- cur_req = #request{tmp_file_name=TmpFilename,
-- tmp_file_fd=Fd} = CurReq,
-- status = get_body, recvd_headers = Headers}=State) ->
+- is_closing = IsClosing,
+- cur_req = #request{tmp_file_name=TmpFilename,
+- tmp_file_fd=Fd} = CurReq,
+- status = get_body,
+- recvd_headers = Headers,
+- status_line = Status_line,
+- raw_headers = Raw_headers
+- }=State) ->
- #request{from=From, stream_to=StreamTo, req_id=ReqId,
-- response_format = Resp_format} = CurReq,
+- response_format = Resp_format,
+- options = Options} = CurReq,
- case IsClosing of
-- true ->
-- {_, Reqs_1} = queue:out(Reqs),
-- case TmpFilename of
-- undefined ->
-- do_reply(State, From, StreamTo, ReqId, Resp_format,
-- {ok, SC, Headers, Buf});
-- _ ->
-- file:close(Fd),
-- do_reply(State, From, StreamTo, ReqId, Resp_format,
-- {ok, SC, Headers, {file, TmpFilename}})
-- end,
-- do_error_reply(State#state{reqs = Reqs_1}, connection_closed),
-- State;
-- _ ->
-- do_error_reply(State, connection_closed),
-- State
+- true ->
+- {_, Reqs_1} = queue:out(Reqs),
+- Body = case TmpFilename of
+- undefined ->
+- Buf;
+- _ ->
+- file:close(Fd),
+- {file, TmpFilename}
+- end,
+- Reply = case get_value(give_raw_headers, Options, false) of
+- true ->
+- {ok, Status_line, Raw_headers, Body};
+- false ->
+- {ok, SC, Headers, Buf}
+- end,
+- do_reply(State, From, StreamTo, ReqId, Resp_format, Reply),
+- do_error_reply(State#state{reqs = Reqs_1}, connection_closed),
+- State;
+- _ ->
+- do_error_reply(State, connection_closed),
+- State
- end.
-
--do_connect(Host, Port, _Options, #state{is_ssl=true, ssl_options=SSLOptions}, Timeout) ->
+-do_connect(Host, Port, Options, #state{is_ssl = true,
+- use_proxy = false,
+- ssl_options = SSLOptions},
+- Timeout) ->
+- Caller_socket_options = get_value(socket_options, Options, []),
+- Other_sock_options = filter_sock_options(SSLOptions ++ Caller_socket_options),
- ssl:connect(Host, Port,
-- [binary, {nodelay, true}, {active, false} | SSLOptions],
-- Timeout);
--do_connect(Host, Port, _Options, _State, Timeout) ->
-- gen_tcp:connect(Host, Port,
-- [binary, {nodelay, true}, {active, false}],
-- Timeout).
--
+- [binary, {nodelay, true}, {active, false} | Other_sock_options],
+- Timeout);
+-do_connect(Host, Port, Options, _State, Timeout) ->
+- Caller_socket_options = get_value(socket_options, Options, []),
+- Other_sock_options = filter_sock_options(Caller_socket_options),
+- gen_tcp:connect(Host, to_integer(Port),
+- [binary, {nodelay, true}, {active, false} | Other_sock_options],
+- Timeout).
+-
+-%% We don't want the caller to specify certain options
+-filter_sock_options(Opts) ->
+- lists:filter(fun({active, _}) ->
+- false;
+- ({packet, _}) ->
+- false;
+- (list) ->
+- false;
+- (_) ->
+- true
+- end, Opts).
+-
+-do_send(Req, #state{socket = Sock,
+- is_ssl = true,
+- use_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).
-
@@ -1955,273 +1608,378 @@ index 65d9cb9..0000000
-%% {fun_arity_0} |
-%% {fun_arity_1, term()}
-%% error() = term()
--do_send_body(Source, State) when is_function(Source) ->
-- do_send_body({Source}, State);
--do_send_body({Source}, State) when is_function(Source) ->
-- do_send_body1(Source, Source(), State);
--do_send_body({Source, Source_state}, State) when is_function(Source) ->
-- do_send_body1(Source, Source(Source_state), State);
--do_send_body(Body, State) ->
+-do_send_body(Source, State, TE) when is_function(Source) ->
+- do_send_body({Source}, State, TE);
+-do_send_body({Source}, State, TE) when is_function(Source) ->
+- do_send_body1(Source, Source(), State, TE);
+-do_send_body({Source, Source_state}, State, TE) when is_function(Source) ->
+- do_send_body1(Source, Source(Source_state), State, TE);
+-do_send_body(Body, State, _TE) ->
- do_send(Body, State).
-
--do_send_body1(Source, Resp, State) ->
+-do_send_body1(Source, Resp, State, TE) ->
- case Resp of
-- {ok, Data} ->
-- do_send(Data, State),
-- do_send_body({Source}, State);
-- {ok, Data, New_source_state} ->
-- do_send(Data, State),
-- do_send_body({Source, New_source_state}, State);
-- eof ->
-- ok;
-- Err ->
-- Err
+- {ok, Data} ->
+- do_send(maybe_chunked_encode(Data, TE), State),
+- do_send_body({Source}, State, TE);
+- {ok, Data, New_source_state} ->
+- do_send(maybe_chunked_encode(Data, TE), State),
+- do_send_body({Source, New_source_state}, State, TE);
+- eof when TE == true ->
+- do_send(<<"0\r\n\r\n">>, State),
+- ok;
+- eof ->
+- ok;
+- Err ->
+- Err
- end.
-
+-maybe_chunked_encode(Data, false) ->
+- Data;
+-maybe_chunked_encode(Data, true) ->
+- [?dec2hex(size(to_binary(Data))), "\r\n", Data, "\r\n"].
+-
-do_close(#state{socket = undefined}) -> ok;
--do_close(#state{socket = Sock, is_ssl = true}) -> ssl:close(Sock);
--do_close(#state{socket = Sock, is_ssl = false}) -> gen_tcp:close(Sock).
+-do_close(#state{socket = Sock,
+- is_ssl = true,
+- use_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);
+-do_close(#state{socket = Sock, is_ssl = false}) -> catch gen_tcp:close(Sock).
-
-active_once(#state{cur_req = #request{caller_controls_socket = true}}) ->
- ok;
--active_once(#state{socket = Socket, is_ssl = Is_ssl}) ->
-- do_setopts(Socket, [{active, once}], Is_ssl).
+-active_once(#state{socket = Socket} = State) ->
+- do_setopts(Socket, [{active, once}], State).
-
--do_setopts(Sock, Opts, true) -> ssl:setopts(Sock, Opts);
--do_setopts(Sock, Opts, false) -> inet:setopts(Sock, Opts).
+-do_setopts(_Sock, [], _) -> ok;
+-do_setopts(Sock, Opts, #state{is_ssl = true,
+- use_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);
+-do_setopts(Sock, Opts, _) -> inet:setopts(Sock, Opts).
-
-check_ssl_options(Options, State) ->
- case get_value(is_ssl, Options, false) of
-- false ->
-- State;
-- true ->
-- State#state{is_ssl=true, ssl_options=get_value(ssl_options, Options)}
+- false ->
+- State;
+- true ->
+- State#state{is_ssl=true, ssl_options=get_value(ssl_options, Options)}
- end.
-
-send_req_1(From,
-- #url{host = Host,
-- port = Port} = Url,
-- Headers, Method, Body, Options, Timeout,
-- #state{socket = undefined} = State) ->
+- #url{host = Host,
+- port = Port} = Url,
+- Headers, Method, Body, Options, Timeout,
+- #state{socket = undefined} = State) ->
- {Host_1, Port_1, State_1} =
-- case get_value(proxy_host, Options, false) of
-- false ->
-- {Host, Port, State};
-- PHost ->
-- 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}}
-- end,
+- case get_value(proxy_host, Options, false) of
+- false ->
+- {Host, Port, State};
+- PHost ->
+- 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}}
+- end,
- State_2 = check_ssl_options(Options, State_1),
- do_trace("Connecting...~n", []),
-- Start_ts = now(),
- Conn_timeout = get_value(connect_timeout, Options, Timeout),
- case do_connect(Host_1, Port_1, Options, State_2, Conn_timeout) of
-- {ok, Sock} ->
-- do_trace("Connected!~n", []),
-- End_ts = now(),
-- Timeout_1 = case Timeout of
-- infinity ->
-- infinity;
-- _ ->
-- Timeout - trunc(round(timer:now_diff(End_ts, Start_ts) / 1000))
-- end,
-- State_3 = State_2#state{socket = Sock},
-- send_req_1(From, Url, Headers, Method, Body, Options, Timeout_1, State_3);
-- Err ->
-- shutting_down(State_2),
-- do_trace("Error connecting. Reason: ~1000.p~n", [Err]),
-- gen_server:reply(From, {error, conn_failed}),
-- {stop, normal, State_2}
+- {ok, Sock} ->
+- do_trace("Connected! Socket: ~1000.p~n", [Sock]),
+- State_3 = State_2#state{socket = Sock,
+- connect_timeout = Conn_timeout},
+- send_req_1(From, Url, Headers, Method, Body, Options, Timeout, State_3);
+- Err ->
+- shutting_down(State_2),
+- do_trace("Error connecting. Reason: ~1000.p~n", [Err]),
+- gen_server:reply(From, {error, {conn_failed, Err}}),
+- {stop, normal, State_2}
- end;
+-
+-%% Send a CONNECT request.
+-%% Wait for 200 OK
+-%% Upgrade to SSL connection
+-%% Then send request
+-
-send_req_1(From,
-- #url{abspath = AbsPath,
-- host = Host,
-- port = Port,
-- path = RelPath} = Url,
-- Headers, Method, Body, Options, Timeout,
-- #state{status = Status} = State) ->
+- #url{
+- host = Server_host,
+- port = Server_port
+- } = Url,
+- Headers, Method, Body, Options, Timeout,
+- #state{
+- proxy_tunnel_setup = false,
+- use_proxy = true,
+- is_ssl = true} = State) ->
+- NewReq = #request{
+- method = connect,
+- preserve_chunked_encoding = get_value(preserve_chunked_encoding, Options, false),
+- options = Options
+- },
+- State_1 = State#state{reqs=queue:in(NewReq, State#state.reqs)},
+- Pxy_auth_headers = maybe_modify_headers(Url, Method, Options, [], State_1),
+- Path = [Server_host, $:, integer_to_list(Server_port)],
+- {Req, Body_1} = make_request(connect, Pxy_auth_headers,
+- Path, Path,
+- [], Options, State_1, undefined),
+- TE = is_chunked_encoding_specified(Options),
+- trace_request(Req),
+- case do_send(Req, State) of
+- ok ->
+- case do_send_body(Body_1, State_1, TE) of
+- ok ->
+- trace_request_body(Body_1),
+- active_once(State_1),
+- Ref = case Timeout of
+- infinity ->
+- undefined;
+- _ ->
+- erlang:send_after(Timeout, self(), {req_timedout, From})
+- end,
+- State_2 = State_1#state{status = get_header,
+- cur_req = NewReq,
+- send_timer = Ref,
+- proxy_tunnel_setup = in_progress,
+- tunnel_setup_queue = [{From, Url, Headers, Method, Body, Options, Timeout}]},
+- State_3 = set_inac_timer(State_2),
+- {noreply, State_3};
+- Err ->
+- shutting_down(State_1),
+- do_trace("Send failed... Reason: ~p~n", [Err]),
+- gen_server:reply(From, {error, {send_failed, Err}}),
+- {stop, normal, State_1}
+- end;
+- Err ->
+- shutting_down(State_1),
+- do_trace("Send failed... Reason: ~p~n", [Err]),
+- gen_server:reply(From, {error, {send_failed, Err}}),
+- {stop, normal, State_1}
+- end;
+-
+-send_req_1(From, Url, Headers, Method, Body, Options, Timeout,
+- #state{proxy_tunnel_setup = in_progress,
+- tunnel_setup_queue = Q} = State) ->
+- do_trace("Queued SSL request awaiting tunnel setup: ~n"
+- "URL : ~s~n"
+- "Method : ~p~n"
+- "Headers : ~p~n", [Url, Method, Headers]),
+- {noreply, State#state{tunnel_setup_queue = [{From, Url, Headers, Method, Body, Options, Timeout} | Q]}};
+-
+-send_req_1(From,
+- #url{abspath = AbsPath,
+- path = RelPath} = Url,
+- Headers, Method, Body, Options, Timeout,
+- #state{status = Status,
+- socket = Socket} = State) ->
+- cancel_timer(State#state.inactivity_timer_ref, {eat_message, timeout}),
- ReqId = make_req_id(),
- Resp_format = get_value(response_format, Options, list),
+- Caller_socket_options = get_value(socket_options, Options, []),
- {StreamTo, Caller_controls_socket} =
-- case get_value(stream_to, Options, undefined) of
-- {Caller, once} when is_pid(Caller) or
-- is_atom(Caller) ->
-- Async_pid_rec = {{req_id_pid, ReqId}, self()},
-- true = ets:insert(ibrowse_stream, Async_pid_rec),
-- {Caller, true};
-- undefined ->
-- {undefined, false};
-- Caller when is_pid(Caller) or
-- is_atom(Caller) ->
-- {Caller, false};
-- Stream_to_inv ->
-- exit({invalid_option, {stream_to, Stream_to_inv}})
-- end,
+- case get_value(stream_to, Options, undefined) of
+- {Caller, once} when is_pid(Caller) or
+- is_atom(Caller) ->
+- Async_pid_rec = {{req_id_pid, ReqId}, self()},
+- true = ets:insert(ibrowse_stream, Async_pid_rec),
+- {Caller, true};
+- undefined ->
+- {undefined, false};
+- Caller when is_pid(Caller) or
+- is_atom(Caller) ->
+- {Caller, false};
+- Stream_to_inv ->
+- exit({invalid_option, {stream_to, Stream_to_inv}})
+- end,
- SaveResponseToFile = get_value(save_response_to_file, Options, false),
- NewReq = #request{url = Url,
-- method = Method,
-- stream_to = StreamTo,
-- caller_controls_socket = Caller_controls_socket,
-- options = Options,
-- req_id = ReqId,
-- save_response_to_file = SaveResponseToFile,
-- stream_chunk_size = get_stream_chunk_size(Options),
-- response_format = Resp_format,
-- from = From},
+- method = Method,
+- stream_to = StreamTo,
+- caller_controls_socket = Caller_controls_socket,
+- caller_socket_options = Caller_socket_options,
+- options = Options,
+- req_id = ReqId,
+- save_response_to_file = SaveResponseToFile,
+- stream_chunk_size = get_stream_chunk_size(Options),
+- response_format = Resp_format,
+- from = From,
+- preserve_chunked_encoding = get_value(preserve_chunked_encoding, Options, false)
+- },
- State_1 = State#state{reqs=queue:in(NewReq, State#state.reqs)},
-- Headers_1 = add_auth_headers(Url, Options, Headers, State),
-- HostHeaderValue = case lists:keysearch(host_header, 1, Options) of
-- false ->
-- case Port of
-- 80 -> Host;
-- _ -> [Host, ":", integer_to_list(Port)]
-- end;
-- {value, {_, Host_h_val}} ->
-- Host_h_val
-- end,
+- Headers_1 = maybe_modify_headers(Url, Method, Options, Headers, State_1),
- {Req, Body_1} = make_request(Method,
-- [{"Host", HostHeaderValue} | Headers_1],
-- AbsPath, RelPath, Body, Options, State#state.use_proxy),
-- case get(my_trace_flag) of
-- true ->
-- %%Avoid the binary operations if trace is not on...
-- NReq = binary_to_list(list_to_binary(Req)),
-- do_trace("Sending request: ~n"
-- "--- Request Begin ---~n~s~n"
-- "--- Request End ---~n", [NReq]);
-- _ -> ok
-- end,
-- case do_send(Req, State) of
-- ok ->
-- case do_send_body(Body_1, State) of
-- ok ->
-- State_2 = inc_pipeline_counter(State_1),
-- active_once(State_1),
-- Ref = case Timeout of
-- infinity ->
-- undefined;
-- _ ->
-- erlang:send_after(Timeout, self(), {req_timedout, From})
-- end,
-- State_3 = case Status of
-- idle ->
-- State_2#state{status = get_header,
-- cur_req = NewReq,
-- send_timer = Ref};
-- _ ->
-- State_2#state{send_timer = Ref}
-- end,
-- case StreamTo of
-- undefined ->
-- ok;
-- _ ->
-- gen_server:reply(From, {ibrowse_req_id, ReqId})
-- end,
-- {noreply, State_3, get_inac_timeout(State_3)};
-- Err ->
-- shutting_down(State_1),
-- do_trace("Send failed... Reason: ~p~n", [Err]),
-- gen_server:reply(From, {error, send_failed}),
-- {stop, normal, State_1}
-- end;
-- Err ->
-- shutting_down(State_1),
-- do_trace("Send failed... Reason: ~p~n", [Err]),
-- gen_server:reply(From, {error, send_failed}),
-- {stop, normal, State_1}
+- Headers_1,
+- AbsPath, RelPath, Body, Options, State_1,
+- ReqId),
+- trace_request(Req),
+- do_setopts(Socket, Caller_socket_options, State_1),
+- TE = is_chunked_encoding_specified(Options),
+- case do_send(Req, State_1) of
+- ok ->
+- case do_send_body(Body_1, State_1, TE) of
+- ok ->
+- trace_request_body(Body_1),
+- State_2 = inc_pipeline_counter(State_1),
+- active_once(State_2),
+- Ref = case Timeout of
+- infinity ->
+- undefined;
+- _ ->
+- erlang:send_after(Timeout, self(), {req_timedout, From})
+- end,
+- State_3 = case Status of
+- idle ->
+- State_2#state{status = get_header,
+- cur_req = NewReq,
+- send_timer = Ref};
+- _ ->
+- State_2#state{send_timer = Ref}
+- end,
+- case StreamTo of
+- undefined ->
+- ok;
+- _ ->
+- gen_server:reply(From, {ibrowse_req_id, ReqId})
+- end,
+- State_4 = set_inac_timer(State_3),
+- {noreply, State_4};
+- Err ->
+- shutting_down(State_1),
+- do_trace("Send failed... Reason: ~p~n", [Err]),
+- gen_server:reply(From, {error, {send_failed, Err}}),
+- {stop, normal, State_1}
+- end;
+- Err ->
+- shutting_down(State_1),
+- do_trace("Send failed... Reason: ~p~n", [Err]),
+- gen_server:reply(From, {error, {send_failed, Err}}),
+- {stop, normal, State_1}
+- end.
+-
+-maybe_modify_headers(#url{}, connect, _, Headers, State) ->
+- add_proxy_auth_headers(State, Headers);
+-maybe_modify_headers(#url{host = Host, port = Port} = Url,
+- _Method,
+- Options, Headers, State) ->
+- case get_value(headers_as_is, Options, false) of
+- false ->
+- Headers_1 = add_auth_headers(Url, Options, Headers, State),
+- HostHeaderValue = case lists:keysearch(host_header, 1, Options) of
+- false ->
+- case Port of
+- 80 -> Host;
+- 443 -> Host;
+- _ -> [Host, ":", integer_to_list(Port)]
+- end;
+- {value, {_, Host_h_val}} ->
+- Host_h_val
+- end,
+- [{"Host", HostHeaderValue} | Headers_1];
+- true ->
+- Headers
- end.
-
-add_auth_headers(#url{username = User,
-- password = UPw},
-- Options,
-- Headers,
-- #state{use_proxy = UseProxy,
-- proxy_auth_digest = ProxyAuthDigest}) ->
+- password = UPw},
+- Options,
+- Headers,
+- State) ->
- Headers_1 = case User of
-- undefined ->
-- case get_value(basic_auth, Options, undefined) of
-- undefined ->
-- Headers;
-- {U,P} ->
-- [{"Authorization", ["Basic ", http_auth_digest(U, P)]} | Headers]
-- end;
-- _ ->
-- [{"Authorization", ["Basic ", http_auth_digest(User, UPw)]} | Headers]
-- end,
-- case UseProxy of
-- false ->
-- Headers_1;
-- true when ProxyAuthDigest == [] ->
-- Headers_1;
-- true ->
-- [{"Proxy-Authorization", ["Basic ", ProxyAuthDigest]} | Headers_1]
-- end.
+- undefined ->
+- case get_value(basic_auth, Options, undefined) of
+- undefined ->
+- Headers;
+- {U,P} ->
+- [{"Authorization", ["Basic ", http_auth_digest(U, P)]} | Headers]
+- end;
+- _ ->
+- [{"Authorization", ["Basic ", http_auth_digest(User, UPw)]} | Headers]
+- end,
+- add_proxy_auth_headers(State, Headers_1).
+-
+-add_proxy_auth_headers(#state{use_proxy = false}, Headers) ->
+- Headers;
+-add_proxy_auth_headers(#state{proxy_auth_digest = []}, Headers) ->
+- Headers;
+-add_proxy_auth_headers(#state{proxy_auth_digest = Auth_digest}, Headers) ->
+- [{"Proxy-Authorization", ["Basic ", Auth_digest]} | Headers].
-
-http_auth_digest([], []) ->
- [];
-http_auth_digest(Username, Password) ->
-- encode_base64(Username ++ [$: | Password]).
+- ibrowse_lib:encode_base64(Username ++ [$: | Password]).
-
--encode_base64([]) ->
-- [];
--encode_base64([A]) ->
-- [e(A bsr 2), e((A band 3) bsl 4), $=, $=];
--encode_base64([A,B]) ->
-- [e(A bsr 2), e(((A band 3) bsl 4) bor (B bsr 4)), e((B band 15) bsl 2), $=];
--encode_base64([A,B,C|Ls]) ->
-- encode_base64_do(A,B,C, Ls).
--encode_base64_do(A,B,C, Rest) ->
-- BB = (A bsl 16) bor (B bsl 8) bor C,
-- [e(BB bsr 18), e((BB bsr 12) band 63),
-- e((BB bsr 6) band 63), e(BB band 63)|encode_base64(Rest)].
--
--e(X) when X >= 0, X < 26 -> X+65;
--e(X) when X>25, X<52 -> X+71;
--e(X) when X>51, X<62 -> X-4;
--e(62) -> $+;
--e(63) -> $/;
--e(X) -> exit({bad_encode_base64_token, X}).
--
--make_request(Method, Headers, AbsPath, RelPath, Body, Options, UseProxy) ->
+-make_request(Method, Headers, AbsPath, RelPath, Body, Options,
+- #state{use_proxy = UseProxy, 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};
+- ({X, Y}) when is_list(X) ->
+- {to_lower(X), X, Y}
+- end,
+- Headers_0 = [Fun1(X) || X <- Headers],
- Headers_1 =
-- case get_value(content_length, Headers, false) of
-- false when (Body == []) or
-- (Body == <<>>) or
-- is_tuple(Body) or
-- is_function(Body) ->
-- Headers;
-- false when is_binary(Body) ->
-- [{"content-length", integer_to_list(size(Body))} | Headers];
-- false ->
-- [{"content-length", integer_to_list(length(Body))} | Headers];
-- _ ->
-- Headers
-- end,
+- case lists:keysearch("content-length", 1, Headers_0) of
+- false when (Body =:= [] orelse Body =:= <<>>) andalso
+- (Method =:= post orelse Method =:= put) ->
+- [{"content-length", "Content-Length", "0"} | Headers_0];
+- false when is_binary(Body) orelse is_list(Body) ->
+- [{"content-length", "Content-Length", integer_to_list(iolist_size(Body))} | Headers_0];
+- _ ->
+- %% Content-Length is already specified or Body is a
+- %% function or function/state pair
+- Headers_0
+- end,
- {Headers_2, Body_1} =
-- case get_value(transfer_encoding, Options, false) of
-- false ->
-- {Headers_1, Body};
-- {chunked, ChunkSize} ->
-- {[{X, Y} || {X, Y} <- Headers_1,
-- X /= "Content-Length",
-- X /= "content-length",
-- X /= content_length] ++
-- [{"Transfer-Encoding", "chunked"}],
-- chunk_request_body(Body, ChunkSize)}
-- end,
-- Headers_3 = cons_headers(Headers_2),
+- case is_chunked_encoding_specified(Options) of
+- false ->
+- {[{Y, Z} || {_, Y, Z} <- Headers_1], Body};
+- true ->
+- Chunk_size_1 = case get_value(transfer_encoding, Options) of
+- chunked ->
+- 5120;
+- {chunked, Chunk_size} ->
+- Chunk_size
+- end,
+- {[{Y, Z} || {X, Y, Z} <- Headers_1,
+- X /= "content-length"] ++
+- [{"Transfer-Encoding", "chunked"}],
+- chunk_request_body(Body, Chunk_size_1)}
+- end,
+- Headers_3 = case lists:member({include_ibrowse_req_id, true}, Options) of
+- true ->
+- [{"x-ibrowse-request-id", io_lib:format("~1000.p",[ReqId])} | Headers_2];
+- false ->
+- Headers_2
+- end,
+- Headers_4 = cons_headers(Headers_3),
- Uri = case get_value(use_absolute_uri, Options, false) or UseProxy of
-- true ->
-- AbsPath;
-- false ->
-- RelPath
-- end,
-- {[method(Method), " ", Uri, " ", HttpVsn, crnl(), Headers_3, crnl()], Body_1}.
+- true ->
+- case Is_ssl of
+- true ->
+- RelPath;
+- false ->
+- AbsPath
+- end;
+- false ->
+- RelPath
+- end,
+- {[method(Method), " ", Uri, " ", HttpVsn, crnl(), Headers_4, crnl()], Body_1}.
+-
+-is_chunked_encoding_specified(Options) ->
+- case get_value(transfer_encoding, Options, false) of
+- false ->
+- false;
+- {chunked, _} ->
+- true;
+- chunked ->
+- true
+- end.
-
-http_vsn_string({0,9}) -> "HTTP/0.9";
-http_vsn_string({1,0}) -> "HTTP/1.0";
@@ -2233,7 +1991,7 @@ index 65d9cb9..0000000
- encode_headers(Acc);
-cons_headers([{basic_auth, {U,P}} | T], Acc) ->
- cons_headers(T, [{"Authorization",
-- ["Basic ", ibrowse_lib:encode_base64(U++":"++P)]} | Acc]);
+- ["Basic ", ibrowse_lib:encode_base64(U++":"++P)]} | Acc]);
-cons_headers([{cookie, Cookie} | T], Acc) ->
- cons_headers(T, [{"Cookie", Cookie} | Acc]);
-cons_headers([{content_length, L} | T], Acc) ->
@@ -2254,6 +2012,9 @@ index 65d9cb9..0000000
-encode_headers([], Acc) ->
- lists:reverse(Acc).
-
+-chunk_request_body(Body, _ChunkSize) when is_tuple(Body) orelse
+- is_function(Body) ->
+- Body;
-chunk_request_body(Body, ChunkSize) ->
- chunk_request_body(Body, ChunkSize, []).
-
@@ -2263,25 +2024,24 @@ index 65d9cb9..0000000
-chunk_request_body(Body, ChunkSize, Acc) when is_binary(Body),
- size(Body) >= ChunkSize ->
- <<ChunkBody:ChunkSize/binary, Rest/binary>> = Body,
-- Chunk = [ibrowse_lib:dec2hex(4, ChunkSize),"\r\n",
-- ChunkBody, "\r\n"],
+- Chunk = [?dec2hex(ChunkSize),"\r\n",
+- ChunkBody, "\r\n"],
- chunk_request_body(Rest, ChunkSize, [Chunk | Acc]);
-chunk_request_body(Body, _ChunkSize, Acc) when is_binary(Body) ->
- BodySize = size(Body),
-- Chunk = [ibrowse_lib:dec2hex(4, BodySize),"\r\n",
-- Body, "\r\n"],
+- Chunk = [?dec2hex(BodySize),"\r\n",
+- Body, "\r\n"],
- LastChunk = "0\r\n",
- lists:reverse(["\r\n", LastChunk, Chunk | Acc]);
--chunk_request_body(Body, ChunkSize, Acc) when is_list(Body),
-- length(Body) >= ChunkSize ->
+-chunk_request_body(Body, ChunkSize, Acc) when length(Body) >= ChunkSize ->
- {ChunkBody, Rest} = split_list_at(Body, ChunkSize),
-- Chunk = [ibrowse_lib:dec2hex(4, ChunkSize),"\r\n",
-- ChunkBody, "\r\n"],
+- Chunk = [?dec2hex(ChunkSize),"\r\n",
+- ChunkBody, "\r\n"],
- chunk_request_body(Rest, ChunkSize, [Chunk | Acc]);
-chunk_request_body(Body, _ChunkSize, Acc) when is_list(Body) ->
- BodySize = length(Body),
-- Chunk = [ibrowse_lib:dec2hex(4, BodySize),"\r\n",
-- Body, "\r\n"],
+- Chunk = [?dec2hex(BodySize),"\r\n",
+- Body, "\r\n"],
- LastChunk = "0\r\n",
- lists:reverse(["\r\n", LastChunk, Chunk | Acc]).
-
@@ -2289,114 +2049,172 @@ index 65d9cb9..0000000
-parse_response(_Data, #state{cur_req = undefined}=State) ->
- State#state{status = idle};
-parse_response(Data, #state{reply_buffer = Acc, reqs = Reqs,
-- cur_req = CurReq} = State) ->
+- cur_req = CurReq} = State) ->
- #request{from=From, stream_to=StreamTo, req_id=ReqId,
-- method=Method, response_format = Resp_format} = CurReq,
+- method=Method, response_format = Resp_format,
+- options = Options
+- } = CurReq,
- MaxHeaderSize = ibrowse:get_config_value(max_headers_size, infinity),
- case scan_header(Acc, Data) of
-- {yes, Headers, Data_1} ->
-- do_trace("Recvd Header Data -> ~s~n----~n", [Headers]),
-- do_trace("Recvd headers~n--- Headers Begin ---~n~s~n--- Headers End ---~n~n", [Headers]),
-- {HttpVsn, StatCode, Headers_1} = parse_headers(Headers),
-- do_trace("HttpVsn: ~p StatusCode: ~p Headers_1 -> ~1000.p~n", [HttpVsn, StatCode, Headers_1]),
-- LCHeaders = [{to_lower(X), Y} || {X,Y} <- Headers_1],
-- ConnClose = to_lower(get_value("connection", LCHeaders, "false")),
-- IsClosing = is_connection_closing(HttpVsn, ConnClose),
-- case IsClosing of
-- true ->
+- {yes, Headers, Data_1} ->
+- do_trace("Recvd Header Data -> ~s~n----~n", [Headers]),
+- do_trace("Recvd headers~n--- Headers Begin ---~n~s~n--- Headers End ---~n~n", [Headers]),
+- {HttpVsn, StatCode, Headers_1, Status_line, Raw_headers} = parse_headers(Headers),
+- do_trace("HttpVsn: ~p StatusCode: ~p Headers_1 -> ~1000.p~n", [HttpVsn, StatCode, Headers_1]),
+- LCHeaders = [{to_lower(X), Y} || {X,Y} <- Headers_1],
+- ConnClose = to_lower(get_value("connection", LCHeaders, "false")),
+- IsClosing = is_connection_closing(HttpVsn, ConnClose),
+- case IsClosing of
+- true ->
- shutting_down(State);
-- false ->
-- ok
-- end,
-- State_1 = State#state{recvd_headers=Headers_1, status=get_body,
-- reply_buffer = <<>>,
-- http_status_code=StatCode, is_closing=IsClosing},
-- put(conn_close, ConnClose),
-- TransferEncoding = to_lower(get_value("transfer-encoding", LCHeaders, "false")),
-- case get_value("content-length", LCHeaders, undefined) of
-- _ when Method == head ->
-- {_, Reqs_1} = queue:out(Reqs),
-- send_async_headers(ReqId, StreamTo, StatCode, Headers_1),
-- State_1_1 = do_reply(State_1, From, StreamTo, ReqId, Resp_format,
-- {ok, StatCode, Headers_1, []}),
-- cancel_timer(State_1_1#state.send_timer, {eat_message, {req_timedout, From}}),
-- State_2 = reset_state(State_1_1),
-- State_3 = set_cur_request(State_2#state{reqs = Reqs_1}),
-- parse_response(Data_1, State_3);
-- _ when hd(StatCode) == $1 ->
-- %% No message body is expected. Server may send
-- %% one or more 1XX responses before a proper
-- %% response.
-- send_async_headers(ReqId, StreamTo, StatCode, Headers_1),
-- do_trace("Recvd a status code of ~p. Ignoring and waiting for a proper response~n", [StatCode]),
-- parse_response(Data_1, State_1#state{recvd_headers = [],
-- status = get_header});
-- _ when StatCode == "204";
-- StatCode == "304" ->
-- %% No message body is expected for these Status Codes.
-- %% RFC2616 - Sec 4.4
-- {_, Reqs_1} = queue:out(Reqs),
-- send_async_headers(ReqId, StreamTo, StatCode, Headers_1),
-- State_1_1 = do_reply(State_1, From, StreamTo, ReqId, Resp_format,
-- {ok, StatCode, Headers_1, []}),
-- cancel_timer(State_1_1#state.send_timer, {eat_message, {req_timedout, From}}),
-- State_2 = reset_state(State_1_1),
-- State_3 = set_cur_request(State_2#state{reqs = Reqs_1}),
-- parse_response(Data_1, State_3);
-- _ when TransferEncoding == "chunked" ->
-- do_trace("Chunked encoding detected...~n",[]),
-- send_async_headers(ReqId, StreamTo, StatCode, Headers_1),
-- case parse_11_response(Data_1, State_1#state{transfer_encoding=chunked,
-- chunk_size=chunk_start,
-- reply_buffer = <<>>}) of
-- {error, Reason} ->
-- fail_pipelined_requests(State_1,
-- {error, {Reason,
-- {stat_code, StatCode}, Headers_1}}),
-- {error, Reason};
-- State_2 ->
-- State_2
-- end;
-- undefined when HttpVsn == "HTTP/1.0";
-- ConnClose == "close" ->
-- send_async_headers(ReqId, StreamTo, StatCode, Headers_1),
-- State_1#state{reply_buffer = Data_1};
-- undefined ->
-- fail_pipelined_requests(State_1,
-- {error, {content_length_undefined,
-- {stat_code, StatCode}, Headers}}),
-- {error, content_length_undefined};
-- V ->
-- case catch list_to_integer(V) of
-- V_1 when is_integer(V_1), V_1 >= 0 ->
-- send_async_headers(ReqId, StreamTo, StatCode, Headers_1),
-- do_trace("Recvd Content-Length of ~p~n", [V_1]),
-- State_2 = State_1#state{rep_buf_size=0,
-- reply_buffer = <<>>,
-- content_length=V_1},
-- case parse_11_response(Data_1, State_2) of
-- {error, Reason} ->
-- fail_pipelined_requests(State_1,
-- {error, {Reason,
-- {stat_code, StatCode}, Headers_1}}),
-- {error, Reason};
-- State_3 ->
-- State_3
-- end;
-- _ ->
-- fail_pipelined_requests(State_1,
-- {error, {content_length_undefined,
-- {stat_code, StatCode}, Headers}}),
-- {error, content_length_undefined}
-- end
-- end;
-- {no, Acc_1} when MaxHeaderSize == infinity ->
-- State#state{reply_buffer = Acc_1};
-- {no, Acc_1} when size(Acc_1) < MaxHeaderSize ->
-- State#state{reply_buffer = Acc_1};
-- {no, _Acc_1} ->
-- fail_pipelined_requests(State, {error, max_headers_size_exceeded}),
-- {error, max_headers_size_exceeded}
+- false ->
+- ok
+- end,
+- Give_raw_headers = get_value(give_raw_headers, Options, false),
+- State_1 = case Give_raw_headers of
+- true ->
+- State#state{recvd_headers=Headers_1, status=get_body,
+- reply_buffer = <<>>,
+- status_line = Status_line,
+- raw_headers = Raw_headers,
+- http_status_code=StatCode, is_closing=IsClosing};
+- false ->
+- State#state{recvd_headers=Headers_1, status=get_body,
+- reply_buffer = <<>>,
+- http_status_code=StatCode, is_closing=IsClosing}
+- end,
+- put(conn_close, ConnClose),
+- TransferEncoding = to_lower(get_value("transfer-encoding", LCHeaders, "false")),
+- case get_value("content-length", LCHeaders, undefined) of
+- _ when Method == connect,
+- hd(StatCode) == $2 ->
+- cancel_timer(State#state.send_timer),
+- {_, Reqs_1} = queue:out(Reqs),
+- upgrade_to_ssl(set_cur_request(State#state{reqs = Reqs_1,
+- recvd_headers = [],
+- status = idle
+- }));
+- _ when Method == connect ->
+- {_, Reqs_1} = queue:out(Reqs),
+- do_error_reply(State#state{reqs = Reqs_1},
+- {error, proxy_tunnel_failed}),
+- {error, proxy_tunnel_failed};
+- _ when Method == head ->
+- {_, Reqs_1} = queue:out(Reqs),
+- send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
+- State_1_1 = do_reply(State_1, From, StreamTo, ReqId, Resp_format,
+- {ok, StatCode, Headers_1, []}),
+- cancel_timer(State_1_1#state.send_timer, {eat_message, {req_timedout, From}}),
+- State_2 = reset_state(State_1_1),
+- State_3 = set_cur_request(State_2#state{reqs = Reqs_1}),
+- parse_response(Data_1, State_3);
+- _ when hd(StatCode) =:= $1 ->
+- %% No message body is expected. Server may send
+- %% one or more 1XX responses before a proper
+- %% response.
+- send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
+- do_trace("Recvd a status code of ~p. Ignoring and waiting for a proper response~n", [StatCode]),
+- parse_response(Data_1, State_1#state{recvd_headers = [],
+- status = get_header});
+- _ when StatCode =:= "204";
+- StatCode =:= "304" ->
+- %% No message body is expected for these Status Codes.
+- %% RFC2616 - Sec 4.4
+- {_, Reqs_1} = queue:out(Reqs),
+- send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
+- State_1_1 = do_reply(State_1, From, StreamTo, ReqId, Resp_format,
+- {ok, StatCode, Headers_1, []}),
+- cancel_timer(State_1_1#state.send_timer, {eat_message, {req_timedout, From}}),
+- State_2 = reset_state(State_1_1),
+- State_3 = set_cur_request(State_2#state{reqs = Reqs_1}),
+- parse_response(Data_1, State_3);
+- _ when TransferEncoding =:= "chunked" ->
+- do_trace("Chunked encoding detected...~n",[]),
+- send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
+- case parse_11_response(Data_1, State_1#state{transfer_encoding=chunked,
+- chunk_size=chunk_start,
+- reply_buffer = <<>>}) of
+- {error, Reason} ->
+- fail_pipelined_requests(State_1,
+- {error, {Reason,
+- {stat_code, StatCode}, Headers_1}}),
+- {error, Reason};
+- State_2 ->
+- State_2
+- end;
+- undefined when HttpVsn =:= "HTTP/1.0";
+- ConnClose =:= "close" ->
+- send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
+- State_1#state{reply_buffer = Data_1};
+- undefined ->
+- fail_pipelined_requests(State_1,
+- {error, {content_length_undefined,
+- {stat_code, StatCode}, Headers}}),
+- {error, content_length_undefined};
+- V ->
+- case catch list_to_integer(V) of
+- V_1 when is_integer(V_1), V_1 >= 0 ->
+- send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
+- do_trace("Recvd Content-Length of ~p~n", [V_1]),
+- State_2 = State_1#state{rep_buf_size=0,
+- reply_buffer = <<>>,
+- content_length=V_1},
+- case parse_11_response(Data_1, State_2) of
+- {error, Reason} ->
+- fail_pipelined_requests(State_1,
+- {error, {Reason,
+- {stat_code, StatCode}, Headers_1}}),
+- {error, Reason};
+- State_3 ->
+- State_3
+- end;
+- _ ->
+- fail_pipelined_requests(State_1,
+- {error, {content_length_undefined,
+- {stat_code, StatCode}, Headers}}),
+- {error, content_length_undefined}
+- end
+- end;
+- {no, Acc_1} when MaxHeaderSize == infinity ->
+- State#state{reply_buffer = Acc_1};
+- {no, Acc_1} when size(Acc_1) < MaxHeaderSize ->
+- State#state{reply_buffer = Acc_1};
+- {no, _Acc_1} ->
+- fail_pipelined_requests(State, {error, max_headers_size_exceeded}),
+- {error, max_headers_size_exceeded}
+- end.
+-
+-upgrade_to_ssl(#state{socket = Socket,
+- connect_timeout = Conn_timeout,
+- ssl_options = Ssl_options,
+- tunnel_setup_queue = Q} = State) ->
+- case ssl:connect(Socket, Ssl_options, Conn_timeout) of
+- {ok, Ssl_socket} ->
+- do_trace("Upgraded to SSL socket!!~n", []),
+- State_1 = State#state{socket = Ssl_socket,
+- proxy_tunnel_setup = done},
+- send_queued_requests(lists:reverse(Q), State_1);
+- Err ->
+- do_trace("Upgrade to SSL socket failed. Reson: ~p~n", [Err]),
+- do_error_reply(State, {error, {send_failed, Err}}),
+- {error, send_failed}
+- end.
+-
+-send_queued_requests([], State) ->
+- do_trace("Sent all queued requests via SSL connection~n", []),
+- State#state{tunnel_setup_queue = []};
+-send_queued_requests([{From, Url, Headers, Method, Body, Options, Timeout} | Q],
+- State) ->
+- case send_req_1(From, Url, Headers, Method, Body, Options, Timeout, State) of
+- {noreply, State_1} ->
+- send_queued_requests(Q, State_1);
+- Err ->
+- do_trace("Error sending queued SSL request: ~n"
+- "URL : ~s~n"
+- "Method : ~p~n"
+- "Headers : ~p~n", [Url, Method, Headers]),
+- do_error_reply(State, {error, {send_failed, Err}}),
+- {error, send_failed}
- end.
-
-is_connection_closing("HTTP/0.9", _) -> true;
@@ -2406,200 +2224,226 @@ index 65d9cb9..0000000
-
-%% This clause determines the chunk size when given data from the beginning of the chunk
-parse_11_response(DataRecvd,
-- #state{transfer_encoding = chunked,
-- chunk_size = chunk_start,
-- chunk_size_buffer = Chunk_sz_buf
-- } = State) ->
+- #state{transfer_encoding = chunked,
+- chunk_size = chunk_start,
+- chunk_size_buffer = Chunk_sz_buf
+- } = State) ->
- case scan_crlf(Chunk_sz_buf, DataRecvd) of
-- {yes, ChunkHeader, Data_1} ->
-- case parse_chunk_header(ChunkHeader) of
-- {error, Reason} ->
-- {error, Reason};
-- ChunkSize ->
-- %%
-- %% Do we have to preserve the chunk encoding when
-- %% streaming? NO. This should be transparent to the client
-- %% process. Chunked encoding was only introduced to make
-- %% it efficient for the server.
-- %%
-- RemLen = size(Data_1),
-- do_trace("Determined chunk size: ~p. Already recvd: ~p~n", [ChunkSize, RemLen]),
-- parse_11_response(Data_1, State#state{chunk_size_buffer = <<>>,
-- deleted_crlf = true,
-- recvd_chunk_size = 0,
-- chunk_size = ChunkSize})
-- end;
-- {no, Data_1} ->
-- State#state{chunk_size_buffer = Data_1}
+- {yes, ChunkHeader, Data_1} ->
+- State_1 = maybe_accumulate_ce_data(State, <<ChunkHeader/binary, $\r, $\n>>),
+- ChunkSize = parse_chunk_header(ChunkHeader),
+- %%
+- %% Do we have to preserve the chunk encoding when
+- %% streaming? NO. This should be transparent to the client
+- %% process. Chunked encoding was only introduced to make
+- %% it efficient for the server.
+- %%
+- RemLen = size(Data_1),
+- do_trace("Determined chunk size: ~p. Already recvd: ~p~n",
+- [ChunkSize, RemLen]),
+- parse_11_response(Data_1, State_1#state{chunk_size_buffer = <<>>,
+- deleted_crlf = true,
+- recvd_chunk_size = 0,
+- chunk_size = ChunkSize});
+- {no, Data_1} ->
+- State#state{chunk_size_buffer = Data_1}
- end;
-
-%% This clause is to remove the CRLF between two chunks
-%%
-parse_11_response(DataRecvd,
-- #state{transfer_encoding = chunked,
-- chunk_size = tbd,
-- chunk_size_buffer = Buf}=State) ->
+- #state{transfer_encoding = chunked,
+- chunk_size = tbd,
+- chunk_size_buffer = Buf
+- } = State) ->
- case scan_crlf(Buf, DataRecvd) of
-- {yes, _, NextChunk} ->
-- State_1 = State#state{chunk_size = chunk_start,
-- chunk_size_buffer = <<>>,
-- deleted_crlf = true},
-- parse_11_response(NextChunk, State_1);
-- {no, Data_1} ->
-- State#state{chunk_size_buffer = Data_1}
+- {yes, _, NextChunk} ->
+- State_1 = maybe_accumulate_ce_data(State, <<$\r, $\n>>),
+- State_2 = State_1#state{chunk_size = chunk_start,
+- chunk_size_buffer = <<>>,
+- deleted_crlf = true},
+- parse_11_response(NextChunk, State_2);
+- {no, Data_1} ->
+- State#state{chunk_size_buffer = Data_1}
- end;
-
-%% This clause deals with the end of a chunked transfer. ibrowse does
-%% not support Trailers in the Chunked Transfer encoding. Any trailer
-%% received is silently discarded.
-parse_11_response(DataRecvd,
-- #state{transfer_encoding = chunked, chunk_size = 0,
-- cur_req = CurReq,
-- deleted_crlf = DelCrlf,
-- chunk_size_buffer = Trailer, reqs = Reqs}=State) ->
+- #state{transfer_encoding = chunked, chunk_size = 0,
+- cur_req = CurReq,
+- deleted_crlf = DelCrlf,
+- chunk_size_buffer = Trailer,
+- reqs = Reqs} = State) ->
- do_trace("Detected end of chunked transfer...~n", []),
- DataRecvd_1 = case DelCrlf of
-- false ->
-- DataRecvd;
-- true ->
-- <<$\r, $\n, DataRecvd/binary>>
+- false ->
+- DataRecvd;
+- true ->
+- <<$\r, $\n, DataRecvd/binary>>
- end,
- case scan_header(Trailer, DataRecvd_1) of
-- {yes, _TEHeaders, Rem} ->
-- {_, Reqs_1} = queue:out(Reqs),
-- State_1 = handle_response(CurReq, State#state{reqs = Reqs_1}),
-- parse_response(Rem, reset_state(State_1));
-- {no, Rem} ->
-- State#state{chunk_size_buffer = Rem, deleted_crlf = false}
+- {yes, TEHeaders, Rem} ->
+- {_, Reqs_1} = queue:out(Reqs),
+- State_1 = maybe_accumulate_ce_data(State, <<TEHeaders/binary, $\r, $\n>>),
+- State_2 = handle_response(CurReq,
+- State_1#state{reqs = Reqs_1}),
+- parse_response(Rem, reset_state(State_2));
+- {no, Rem} ->
+- accumulate_response(<<>>, State#state{chunk_size_buffer = Rem, deleted_crlf = false})
- end;
-
-%% This clause extracts a chunk, given the size.
-parse_11_response(DataRecvd,
-- #state{transfer_encoding = chunked,
-- chunk_size = CSz,
-- recvd_chunk_size = Recvd_csz,
-- rep_buf_size = RepBufSz} = State) ->
+- #state{transfer_encoding = chunked,
+- chunk_size = CSz,
+- recvd_chunk_size = Recvd_csz,
+- rep_buf_size = RepBufSz} = State) ->
- NeedBytes = CSz - Recvd_csz,
- DataLen = size(DataRecvd),
- do_trace("Recvd more data: size: ~p. NeedBytes: ~p~n", [DataLen, NeedBytes]),
- case DataLen >= NeedBytes of
-- true ->
-- {RemChunk, RemData} = split_binary(DataRecvd, NeedBytes),
-- do_trace("Recvd another chunk...~n", []),
-- do_trace("RemData -> ~p~n", [RemData]),
-- case accumulate_response(RemChunk, State) of
-- {error, Reason} ->
-- do_trace("Error accumulating response --> ~p~n", [Reason]),
-- {error, Reason};
-- #state{} = State_1 ->
-- State_2 = State_1#state{chunk_size=tbd},
-- parse_11_response(RemData, State_2)
-- end;
-- false ->
-- accumulate_response(DataRecvd,
-- State#state{rep_buf_size = RepBufSz + DataLen,
-- recvd_chunk_size = Recvd_csz + DataLen})
+- true ->
+- {RemChunk, RemData} = split_binary(DataRecvd, NeedBytes),
+- do_trace("Recvd another chunk...~p~n", [RemChunk]),
+- do_trace("RemData -> ~p~n", [RemData]),
+- case accumulate_response(RemChunk, State) of
+- {error, Reason} ->
+- do_trace("Error accumulating response --> ~p~n", [Reason]),
+- {error, Reason};
+- #state{} = State_1 ->
+- State_2 = State_1#state{chunk_size=tbd},
+- parse_11_response(RemData, State_2)
+- end;
+- false ->
+- accumulate_response(DataRecvd,
+- State#state{rep_buf_size = RepBufSz + DataLen,
+- recvd_chunk_size = Recvd_csz + DataLen})
- end;
-
-%% This clause to extract the body when Content-Length is specified
-parse_11_response(DataRecvd,
-- #state{content_length=CL, rep_buf_size=RepBufSz,
-- reqs=Reqs}=State) ->
+- #state{content_length=CL, rep_buf_size=RepBufSz,
+- reqs=Reqs}=State) ->
- NeedBytes = CL - RepBufSz,
- DataLen = size(DataRecvd),
- case DataLen >= NeedBytes of
-- true ->
-- {RemBody, Rem} = split_binary(DataRecvd, NeedBytes),
-- {_, Reqs_1} = queue:out(Reqs),
-- State_1 = accumulate_response(RemBody, State),
-- State_2 = handle_response(State_1#state.cur_req, State_1#state{reqs=Reqs_1}),
-- State_3 = reset_state(State_2),
-- parse_response(Rem, State_3);
-- false ->
-- accumulate_response(DataRecvd, State#state{rep_buf_size = (RepBufSz+DataLen)})
+- true ->
+- {RemBody, Rem} = split_binary(DataRecvd, NeedBytes),
+- {_, Reqs_1} = queue:out(Reqs),
+- State_1 = accumulate_response(RemBody, State),
+- State_2 = handle_response(State_1#state.cur_req, State_1#state{reqs=Reqs_1}),
+- State_3 = reset_state(State_2),
+- parse_response(Rem, State_3);
+- false ->
+- accumulate_response(DataRecvd, State#state{rep_buf_size = (RepBufSz+DataLen)})
- end.
-
+-maybe_accumulate_ce_data(#state{cur_req = #request{preserve_chunked_encoding = false}} = State, _) ->
+- State;
+-maybe_accumulate_ce_data(State, Data) ->
+- accumulate_response(Data, State).
+-
-handle_response(#request{from=From, stream_to=StreamTo, req_id=ReqId,
-- response_format = Resp_format,
-- save_response_to_file = SaveResponseToFile,
-- tmp_file_name = TmpFilename,
-- tmp_file_fd = Fd
-- },
-- #state{http_status_code = SCode,
-- send_timer = ReqTimer,
-- reply_buffer = RepBuf,
-- recvd_headers = RespHeaders}=State) when SaveResponseToFile /= false ->
+- response_format = Resp_format,
+- save_response_to_file = SaveResponseToFile,
+- tmp_file_name = TmpFilename,
+- tmp_file_fd = Fd,
+- options = Options
+- },
+- #state{http_status_code = SCode,
+- status_line = Status_line,
+- raw_headers = Raw_headers,
+- send_timer = ReqTimer,
+- reply_buffer = RepBuf,
+- recvd_headers = RespHeaders}=State) when SaveResponseToFile /= false ->
- Body = RepBuf,
-- State_1 = set_cur_request(State),
- file:close(Fd),
- ResponseBody = case TmpFilename of
-- undefined ->
-- Body;
-- _ ->
-- {file, TmpFilename}
-- end,
-- State_2 = do_reply(State_1, From, StreamTo, ReqId, Resp_format,
-- {ok, SCode, RespHeaders, ResponseBody}),
+- undefined ->
+- Body;
+- _ ->
+- {file, TmpFilename}
+- end,
+- {Resp_headers_1, Raw_headers_1} = maybe_add_custom_headers(RespHeaders, Raw_headers, Options),
+- Reply = case get_value(give_raw_headers, Options, false) of
+- true ->
+- {ok, Status_line, Raw_headers_1, ResponseBody};
+- false ->
+- {ok, SCode, Resp_headers_1, ResponseBody}
+- end,
+- State_1 = do_reply(State, From, StreamTo, ReqId, Resp_format, Reply),
- cancel_timer(ReqTimer, {eat_message, {req_timedout, From}}),
-- State_2;
+- set_cur_request(State_1);
-handle_response(#request{from=From, stream_to=StreamTo, req_id=ReqId,
-- response_format = Resp_format},
-- #state{http_status_code=SCode, recvd_headers=RespHeaders,
-- reply_buffer = RepBuf,
-- send_timer=ReqTimer}=State) ->
+- response_format = Resp_format,
+- options = Options},
+- #state{http_status_code = SCode,
+- status_line = Status_line,
+- raw_headers = Raw_headers,
+- recvd_headers = Resp_headers,
+- reply_buffer = RepBuf,
+- send_timer = ReqTimer} = State) ->
- Body = RepBuf,
--%% State_1 = set_cur_request(State),
-- State_1 = case get(conn_close) of
-- "close" ->
-- do_reply(State, From, StreamTo, ReqId, Resp_format,
-- {ok, SCode, RespHeaders, Body}),
-- exit(normal);
-- _ ->
-- State_1_1 = do_reply(State, From, StreamTo, ReqId, Resp_format,
-- {ok, SCode, RespHeaders, Body}),
-- cancel_timer(ReqTimer, {eat_message, {req_timedout, From}}),
-- State_1_1
-- end,
+- {Resp_headers_1, Raw_headers_1} = maybe_add_custom_headers(Resp_headers, Raw_headers, Options),
+- Reply = case get_value(give_raw_headers, Options, false) of
+- true ->
+- {ok, Status_line, Raw_headers_1, Body};
+- false ->
+- {ok, SCode, Resp_headers_1, Body}
+- end,
+- State_1 = do_reply(State, From, StreamTo, ReqId, Resp_format, Reply),
+- cancel_timer(ReqTimer, {eat_message, {req_timedout, From}}),
- set_cur_request(State_1).
-
-reset_state(State) ->
- State#state{status = get_header,
-- rep_buf_size = 0,
-- streamed_size = 0,
-- content_length = undefined,
-- reply_buffer = <<>>,
-- chunk_size_buffer = <<>>,
-- recvd_headers = [],
-- deleted_crlf = false,
-- http_status_code = undefined,
-- chunk_size = undefined,
-- transfer_encoding = undefined}.
--
--set_cur_request(#state{reqs = Reqs} = State) ->
+- rep_buf_size = 0,
+- streamed_size = 0,
+- content_length = undefined,
+- reply_buffer = <<>>,
+- chunk_size_buffer = <<>>,
+- recvd_headers = [],
+- status_line = undefined,
+- raw_headers = undefined,
+- deleted_crlf = false,
+- http_status_code = undefined,
+- chunk_size = undefined,
+- transfer_encoding = undefined
+- }.
+-
+-set_cur_request(#state{reqs = Reqs, socket = Socket} = State) ->
- case queue:to_list(Reqs) of
-- [] ->
-- State#state{cur_req = undefined};
-- [NextReq | _] ->
-- State#state{cur_req = NextReq}
+- [] ->
+- State#state{cur_req = undefined};
+- [#request{caller_controls_socket = Ccs} = NextReq | _] ->
+- case Ccs of
+- true ->
+- do_setopts(Socket, [{active, once}], State);
+- _ ->
+- ok
+- end,
+- State#state{cur_req = NextReq}
- end.
-
-parse_headers(Headers) ->
- case scan_crlf(Headers) of
-- {yes, StatusLine, T} ->
-- parse_headers(StatusLine, T);
-- {no, StatusLine} ->
-- parse_headers(StatusLine, <<>>)
+- {yes, StatusLine, T} ->
+- parse_headers(StatusLine, T);
+- {no, StatusLine} ->
+- parse_headers(StatusLine, <<>>)
- end.
-
-parse_headers(StatusLine, Headers) ->
- Headers_1 = parse_headers_1(Headers),
- case parse_status_line(StatusLine) of
-- {ok, HttpVsn, StatCode, _Msg} ->
-- put(http_prot_vsn, HttpVsn),
-- {HttpVsn, StatCode, Headers_1};
-- _ -> %% A HTTP 0.9 response?
-- put(http_prot_vsn, "HTTP/0.9"),
-- {"HTTP/0.9", undefined, Headers}
+- {ok, HttpVsn, StatCode, _Msg} ->
+- put(http_prot_vsn, HttpVsn),
+- {HttpVsn, StatCode, Headers_1, StatusLine, Headers};
+- _ -> %% A HTTP 0.9 response?
+- put(http_prot_vsn, "HTTP/0.9"),
+- {"HTTP/0.9", undefined, Headers, StatusLine, Headers}
- end.
-
-% From RFC 2616
@@ -2610,22 +2454,22 @@ index 65d9cb9..0000000
-% SP. A recipient MAY replace any linear white space with a single
-% SP before interpreting the field value or forwarding the message
-% downstream.
-- parse_headers_1(B) when is_binary(B) ->
-- parse_headers_1(binary_to_list(B));
-- parse_headers_1(String) ->
-- parse_headers_1(String, [], []).
+-parse_headers_1(B) when is_binary(B) ->
+- parse_headers_1(binary_to_list(B));
+-parse_headers_1(String) ->
+- parse_headers_1(String, [], []).
-
--parse_headers_1([$\n, H |T], [$\r | L], Acc) when H == 32;
-- H == $\t ->
+-parse_headers_1([$\n, H |T], [$\r | L], Acc) when H =:= 32;
+- H =:= $\t ->
- parse_headers_1(lists:dropwhile(fun(X) ->
-- is_whitespace(X)
-- end, T), [32 | L], Acc);
+- is_whitespace(X)
+- end, T), [32 | L], Acc);
-parse_headers_1([$\n|T], [$\r | L], Acc) ->
- case parse_header(lists:reverse(L)) of
-- invalid ->
-- parse_headers_1(T, [], Acc);
-- NewHeader ->
-- parse_headers_1(T, [], [NewHeader | Acc])
+- invalid ->
+- parse_headers_1(T, [], Acc);
+- NewHeader ->
+- parse_headers_1(T, [], [NewHeader | Acc])
- end;
-parse_headers_1([H|T], L, Acc) ->
- parse_headers_1(T, [H|L], Acc);
@@ -2633,11 +2477,11 @@ index 65d9cb9..0000000
- lists:reverse(Acc);
-parse_headers_1([], L, Acc) ->
- Acc_1 = case parse_header(lists:reverse(L)) of
-- invalid ->
-- Acc;
-- NewHeader ->
-- [NewHeader | Acc]
-- end,
+- invalid ->
+- Acc;
+- NewHeader ->
+- [NewHeader | Acc]
+- end,
- lists:reverse(Acc_1).
-
-parse_status_line(Line) when is_binary(Line) ->
@@ -2648,6 +2492,8 @@ index 65d9cb9..0000000
- parse_status_line(T, get_status_code, ProtVsn, StatCode);
-parse_status_line([32 | T], get_status_code, ProtVsn, StatCode) ->
- {ok, lists:reverse(ProtVsn), lists:reverse(StatCode), T};
+-parse_status_line([], get_status_code, ProtVsn, StatCode) ->
+- {ok, lists:reverse(ProtVsn), lists:reverse(StatCode), []};
-parse_status_line([H | T], get_prot_vsn, ProtVsn, StatCode) ->
- parse_status_line(T, get_prot_vsn, [H|ProtVsn], StatCode);
-parse_status_line([H | T], get_status_code, ProtVsn, StatCode) ->
@@ -2655,10 +2501,9 @@ index 65d9cb9..0000000
-parse_status_line([], _, _, _) ->
- http_09.
-
--parse_header(B) when is_binary(B) ->
-- parse_header(binary_to_list(B));
-parse_header(L) ->
- parse_header(L, []).
+-
-parse_header([$: | V], Acc) ->
- {lists:reverse(Acc), string:strip(V)};
-parse_header([H | T], Acc) ->
@@ -2668,11 +2513,11 @@ index 65d9cb9..0000000
-
-scan_header(Bin) ->
- case get_crlf_crlf_pos(Bin, 0) of
-- {yes, Pos} ->
-- {Headers, <<_:4/binary, Body/binary>>} = split_binary(Bin, Pos),
-- {yes, Headers, Body};
-- no ->
-- {no, Bin}
+- {yes, Pos} ->
+- {Headers, <<_:4/binary, Body/binary>>} = split_binary(Bin, Pos),
+- {yes, Headers, Body};
+- no ->
+- {no, Bin}
- end.
-
-scan_header(Bin1, Bin2) when size(Bin1) < 4 ->
@@ -2684,11 +2529,11 @@ index 65d9cb9..0000000
- <<Headers_prefix:Bin1_already_scanned_size/binary, Rest/binary>> = Bin1,
- Bin_to_scan = <<Rest/binary, Bin2/binary>>,
- case get_crlf_crlf_pos(Bin_to_scan, 0) of
-- {yes, Pos} ->
-- {Headers_suffix, <<_:4/binary, Body/binary>>} = split_binary(Bin_to_scan, Pos),
-- {yes, <<Headers_prefix/binary, Headers_suffix/binary>>, Body};
-- no ->
-- {no, <<Bin1/binary, Bin2/binary>>}
+- {yes, Pos} ->
+- {Headers_suffix, <<_:4/binary, Body/binary>>} = split_binary(Bin_to_scan, Pos),
+- {yes, <<Headers_prefix/binary, Headers_suffix/binary>>, Body};
+- no ->
+- {no, <<Bin1/binary, Bin2/binary>>}
- end.
-
-get_crlf_crlf_pos(<<$\r, $\n, $\r, $\n, _/binary>>, Pos) -> {yes, Pos};
@@ -2697,11 +2542,11 @@ index 65d9cb9..0000000
-
-scan_crlf(Bin) ->
- case get_crlf_pos(Bin) of
-- {yes, Pos} ->
-- {Prefix, <<_, _, Suffix/binary>>} = split_binary(Bin, Pos),
-- {yes, Prefix, Suffix};
-- no ->
-- {no, Bin}
+- {yes, Pos} ->
+- {Prefix, <<_, _, Suffix/binary>>} = split_binary(Bin, Pos),
+- {yes, Prefix, Suffix};
+- no ->
+- {no, Bin}
- end.
-
-scan_crlf(<<>>, Bin2) ->
@@ -2715,11 +2560,11 @@ index 65d9cb9..0000000
- <<Bin1_head:Bin1_head_size/binary, Bin1_tail/binary>> = Bin1,
- Bin3 = <<Bin1_tail/binary, Bin2/binary>>,
- case get_crlf_pos(Bin3) of
-- {yes, Pos} ->
-- {Prefix, <<_, _, Suffix/binary>>} = split_binary(Bin3, Pos),
-- {yes, list_to_binary([Bin1_head, Prefix]), Suffix};
-- no ->
-- {no, list_to_binary([Bin1, Bin2])}
+- {yes, Pos} ->
+- {Prefix, <<_, _, Suffix/binary>>} = split_binary(Bin3, Pos),
+- {yes, list_to_binary([Bin1_head, Prefix]), Suffix};
+- no ->
+- {no, list_to_binary([Bin1, Bin2])}
- end.
-
-get_crlf_pos(Bin) ->
@@ -2729,13 +2574,6 @@ index 65d9cb9..0000000
-get_crlf_pos(<<_, Rest/binary>>, Pos) -> get_crlf_pos(Rest, Pos + 1);
-get_crlf_pos(<<>>, _) -> no.
-
--%% scan_crlf(<<$\n, T/binary>>, [$\r | L]) -> {yes, lists:reverse(L), T};
--%% scan_crlf(<<H, T/binary>>, L) -> scan_crlf(T, [H|L]);
--%% scan_crlf(<<>>, L) -> {no, L};
--%% scan_crlf([$\n|T], [$\r | L]) -> {yes, lists:reverse(L), T};
--%% scan_crlf([H|T], L) -> scan_crlf(T, [H|L]);
--%% scan_crlf([], L) -> {no, L}.
--
-fmt_val(L) when is_list(L) -> L;
-fmt_val(I) when is_integer(I) -> integer_to_list(I);
-fmt_val(A) when is_atom(A) -> atom_to_list(A);
@@ -2756,7 +2594,8 @@ index 65d9cb9..0000000
-method(lock) -> "LOCK";
-method(unlock) -> "UNLOCK";
-method(move) -> "MOVE";
--method(copy) -> "COPY".
+-method(copy) -> "COPY";
+-method(connect) -> "CONNECT".
-
-%% From RFC 2616
-%%
@@ -2766,19 +2605,19 @@ index 65d9cb9..0000000
-% fields. This allows dynamically produced content to be transferred
-% along with the information necessary for the recipient to verify
-% that it has received the full message.
--% Chunked-Body = *chunk
--% last-chunk
--% trailer
--% CRLF
--% chunk = chunk-size [ chunk-extension ] CRLF
--% chunk-data CRLF
--% chunk-size = 1*HEX
--% last-chunk = 1*("0") [ chunk-extension ] CRLF
--% chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
--% chunk-ext-name = token
--% chunk-ext-val = token | quoted-string
--% chunk-data = chunk-size(OCTET)
--% trailer = *(entity-header CRLF)
+-% Chunked-Body = *chunk
+-% last-chunk
+-% trailer
+-% CRLF
+-% chunk = chunk-size [ chunk-extension ] CRLF
+-% chunk-data CRLF
+-% chunk-size = 1*HEX
+-% last-chunk = 1*("0") [ chunk-extension ] CRLF
+-% chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+-% chunk-ext-name = token
+-% chunk-ext-val = token | quoted-string
+-% chunk-data = chunk-size(OCTET)
+-% trailer = *(entity-header CRLF)
-% The chunk-size field is a string of hex digits indicating the size
-% of the chunk. The chunked encoding is ended by any chunk whose size
-% is zero, followed by the trailer, which is terminated by an empty
@@ -2787,8 +2626,6 @@ index 65d9cb9..0000000
-%% The parsing implemented here discards all chunk extensions. It also
-%% strips trailing spaces from the chunk size fields as Apache 1.3.27 was
-%% sending them.
--parse_chunk_header([]) ->
-- throw({error, invalid_chunk_size});
-parse_chunk_header(ChunkHeader) ->
- parse_chunk_header(ChunkHeader, []).
-
@@ -2796,10 +2633,10 @@ index 65d9cb9..0000000
- hexlist_to_integer(lists:reverse(Acc));
-parse_chunk_header(<<H, T/binary>>, Acc) ->
- case is_whitespace(H) of
-- true ->
-- parse_chunk_header(T, Acc);
-- false ->
-- parse_chunk_header(T, [H | Acc])
+- true ->
+- parse_chunk_header(T, Acc);
+- false ->
+- parse_chunk_header(T, [H | Acc])
- end;
-parse_chunk_header(<<>>, Acc) ->
- hexlist_to_integer(lists:reverse(Acc)).
@@ -2810,24 +2647,45 @@ index 65d9cb9..0000000
-is_whitespace($\t) -> true;
-is_whitespace(_) -> false.
-
--
--send_async_headers(_ReqId, undefined, _StatCode, _Headers) ->
+-send_async_headers(_ReqId, undefined, _, _State) ->
- ok;
--send_async_headers(ReqId, StreamTo, StatCode, Headers) ->
-- catch StreamTo ! {ibrowse_async_headers, ReqId, StatCode, Headers}.
+-send_async_headers(ReqId, StreamTo, Give_raw_headers,
+- #state{status_line = Status_line, raw_headers = Raw_headers,
+- recvd_headers = Headers, http_status_code = StatCode,
+- cur_req = #request{options = Opts}
+- }) ->
+- {Headers_1, Raw_headers_1} = maybe_add_custom_headers(Headers, Raw_headers, Opts),
+- case Give_raw_headers of
+- false ->
+- catch StreamTo ! {ibrowse_async_headers, ReqId, StatCode, Headers_1};
+- true ->
+- catch StreamTo ! {ibrowse_async_headers, ReqId, Status_line, Raw_headers_1}
+- end.
+-
+-maybe_add_custom_headers(Headers, Raw_headers, Opts) ->
+- Custom_headers = get_value(add_custom_headers, Opts, []),
+- Headers_1 = Headers ++ Custom_headers,
+- Raw_headers_1 = case Custom_headers of
+- [_ | _] when is_binary(Raw_headers) ->
+- Custom_headers_bin = list_to_binary(string:join([[X, $:, Y] || {X, Y} <- Custom_headers], "\r\n")),
+- <<Raw_headers/binary, "\r\n", Custom_headers_bin/binary>>;
+- _ ->
+- Raw_headers
+- end,
+- {Headers_1, Raw_headers_1}.
-
-format_response_data(Resp_format, Body) ->
- case Resp_format of
-- list when is_list(Body) ->
-- flatten(Body);
-- list when is_binary(Body) ->
-- binary_to_list(Body);
-- binary when is_list(Body) ->
-- list_to_binary(Body);
-- _ ->
-- %% This is to cater for sending messages such as
-- %% {chunk_start, _}, chunk_end etc
-- Body
+- list when is_list(Body) ->
+- flatten(Body);
+- list when is_binary(Body) ->
+- binary_to_list(Body);
+- binary when is_list(Body) ->
+- list_to_binary(Body);
+- _ ->
+- %% This is to cater for sending messages such as
+- %% {chunk_start, _}, chunk_end etc
+- Body
- end.
-
-do_reply(State, From, undefined, _, Resp_format, {ok, St_code, Headers, Body}) ->
@@ -2838,14 +2696,14 @@ index 65d9cb9..0000000
- gen_server:reply(From, Msg),
- dec_pipeline_counter(State);
-do_reply(#state{prev_req_id = Prev_req_id} = State,
-- _From, StreamTo, ReqId, Resp_format, {ok, _, _, Body}) ->
+- _From, StreamTo, ReqId, Resp_format, {ok, _, _, Body}) ->
- State_1 = dec_pipeline_counter(State),
- case Body of
-- [] ->
-- ok;
-- _ ->
-- Body_1 = format_response_data(Resp_format, Body),
-- catch StreamTo ! {ibrowse_async_response, ReqId, Body_1}
+- [] ->
+- ok;
+- _ ->
+- Body_1 = format_response_data(Resp_format, Body),
+- catch StreamTo ! {ibrowse_async_response, ReqId, Body_1}
- end,
- catch StreamTo ! {ibrowse_async_response_end, ReqId},
- %% We don't want to delete the Req-id to Pid mapping straightaway
@@ -2872,23 +2730,28 @@ index 65d9cb9..0000000
- Msg_1 = format_response_data(Response_format, Msg),
- catch StreamTo ! {ibrowse_async_response, ReqId, Msg_1}.
-
--do_error_reply(#state{reqs = Reqs} = State, Err) ->
+-do_error_reply(#state{reqs = Reqs, tunnel_setup_queue = Tun_q} = State, Err) ->
- ReqList = queue:to_list(Reqs),
- lists:foreach(fun(#request{from=From, stream_to=StreamTo, req_id=ReqId,
-- response_format = Resp_format}) ->
-- ets:delete(ibrowse_stream, {req_id_pid, ReqId}),
+- response_format = Resp_format}) ->
+- ets:delete(ibrowse_stream, {req_id_pid, ReqId}),
- do_reply(State, From, StreamTo, ReqId, Resp_format, {error, Err})
-- end, ReqList).
+- end, ReqList),
+- lists:foreach(
+- fun({From, _Url, _Headers, _Method, _Body, _Options, _Timeout}) ->
+- do_reply(State, From, undefined, undefined, undefined, Err)
+- end, Tun_q).
-
-fail_pipelined_requests(#state{reqs = Reqs, cur_req = CurReq} = State, Reply) ->
- {_, Reqs_1} = queue:out(Reqs),
- #request{from=From, stream_to=StreamTo, req_id=ReqId,
-- response_format = Resp_format} = CurReq,
+- response_format = Resp_format} = CurReq,
- do_reply(State, From, StreamTo, ReqId, Resp_format, Reply),
- do_error_reply(State#state{reqs = Reqs_1}, previous_request_failed).
-
-split_list_at(List, N) ->
- split_list_at(List, N, []).
+-
-split_list_at([], _, Acc) ->
- {lists:reverse(Acc), []};
-split_list_at(List2, 0, List1) ->
@@ -2898,6 +2761,7 @@ index 65d9cb9..0000000
-
-hexlist_to_integer(List) ->
- hexlist_to_integer(lists:reverse(List), 1, 0).
+-
-hexlist_to_integer([H | T], Multiplier, Acc) ->
- hexlist_to_integer(T, Multiplier*16, Multiplier*to_ascii(H) + Acc);
-hexlist_to_integer([], _, Acc) ->
@@ -2932,10 +2796,10 @@ index 65d9cb9..0000000
-cancel_timer(Ref, {eat_message, Msg}) ->
- cancel_timer(Ref),
- receive
-- Msg ->
-- ok
+- Msg ->
+- ok
- after 0 ->
-- ok
+- ok
- end.
-
-make_req_id() ->
@@ -2953,7 +2817,7 @@ index 65d9cb9..0000000
-shutting_down(#state{lb_ets_tid = undefined}) ->
- ok;
-shutting_down(#state{lb_ets_tid = Tid,
-- cur_pipeline_size = Sz}) ->
+- cur_pipeline_size = Sz}) ->
- catch ets:delete(Tid, {Sz, self()}).
-
-inc_pipeline_counter(#state{is_closing = true} = State) ->
@@ -2966,7 +2830,7 @@ index 65d9cb9..0000000
-dec_pipeline_counter(#state{lb_ets_tid = undefined} = State) ->
- State;
-dec_pipeline_counter(#state{cur_pipeline_size = Pipe_sz,
-- lb_ets_tid = Tid} = State) ->
+- lb_ets_tid = Tid} = State) ->
- ets:delete(Tid, {Pipe_sz, self()}),
- ets:insert(Tid, {{Pipe_sz - 1, self()}, []}),
- State#state{cur_pipeline_size = Pipe_sz - 1}.
@@ -2980,32 +2844,85 @@ index 65d9cb9..0000000
-
-get_stream_chunk_size(Options) ->
- case lists:keysearch(stream_chunk_size, 1, Options) of
-- {value, {_, V}} when V > 0 ->
-- V;
-- _ ->
-- ?DEFAULT_STREAM_CHUNK_SIZE
+- {value, {_, V}} when V > 0 ->
+- V;
+- _ ->
+- ?DEFAULT_STREAM_CHUNK_SIZE
- end.
-
--get_inac_timeout(#state{cur_req = #request{options = Opts}}) ->
+-set_inac_timer(State) ->
+- cancel_timer(State#state.inactivity_timer_ref),
+- set_inac_timer(State#state{inactivity_timer_ref = undefined},
+- get_inac_timeout(State)).
+-
+-set_inac_timer(State, Timeout) when is_integer(Timeout) ->
+- Ref = erlang:send_after(Timeout, self(), timeout),
+- State#state{inactivity_timer_ref = Ref};
+-set_inac_timer(State, _) ->
+- State.
+-
+-get_inac_timeout(#state{cur_req = #request{options = Opts}}) ->
- get_value(inactivity_timeout, Opts, infinity);
-get_inac_timeout(#state{cur_req = undefined}) ->
-- infinity.
+- case ibrowse:get_config_value(inactivity_timeout, undefined) of
+- Val when is_integer(Val) ->
+- Val;
+- _ ->
+- case application:get_env(ibrowse, inactivity_timeout) of
+- {ok, Val} when is_integer(Val), Val > 0 ->
+- Val;
+- _ ->
+- 10000
+- end
+- end.
+-
+-trace_request(Req) ->
+- case get(my_trace_flag) of
+- true ->
+- %%Avoid the binary operations if trace is not on...
+- NReq = to_binary(Req),
+- do_trace("Sending request: ~n"
+- "--- Request Begin ---~n~s~n"
+- "--- Request End ---~n", [NReq]);
+- _ -> ok
+- end.
+-
+-trace_request_body(Body) ->
+- case get(my_trace_flag) of
+- true ->
+- %%Avoid the binary operations if trace is not on...
+- NBody = to_binary(Body),
+- case size(NBody) > 1024 of
+- true ->
+- ok;
+- false ->
+- do_trace("Sending request body: ~n"
+- "--- Request Body Begin ---~n~s~n"
+- "--- Request Body End ---~n", [NBody])
+- end;
+- false ->
+- ok
+- end.
+-
+-to_integer(X) when is_list(X) -> list_to_integer(X);
+-to_integer(X) when is_integer(X) -> X.
+-
+-to_binary(X) when is_list(X) -> list_to_binary(X);
+-to_binary(X) when is_binary(X) -> X.
diff --git a/src/ibrowse/ibrowse_lb.erl b/src/ibrowse/ibrowse_lb.erl
deleted file mode 100644
-index 834054a..0000000
+index 0e001d4..0000000
--- a/src/ibrowse/ibrowse_lb.erl
+++ /dev/null
-@@ -1,216 +0,0 @@
+@@ -1,235 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ibrowse_lb.erl
-%%% Author : chandru <chandrashekhar.mullaparthi at t-mobile.co.uk>
--%%% Description :
+-%%% Description :
-%%%
-%%% Created : 6 Mar 2008 by chandru <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%%%-------------------------------------------------------------------
--module(ibrowse_lb).
--
---vsn('$Id: ibrowse_lb.erl,v 1.2 2009/07/01 22:43:19 chandrusf Exp $ ').
--author(chandru).
--behaviour(gen_server).
-%%--------------------------------------------------------------------
@@ -3016,7 +2933,8 @@ index 834054a..0000000
-%% External exports
--export([
- start_link/1,
-- spawn_connection/5
+- spawn_connection/5,
+- stop/1
- ]).
-
-%% gen_server callbacks
@@ -3085,6 +3003,14 @@ index 834054a..0000000
- is_integer(Max_sessions) ->
- gen_server:call(Lb_pid,
- {spawn_connection, Url, Max_sessions, Max_pipeline_size, SSL_options}).
+-
+-stop(Lb_pid) ->
+- case catch gen_server:call(Lb_pid, stop) of
+- {'EXIT', {timeout, _}} ->
+- exit(Lb_pid, kill);
+- ok ->
+- ok
+- end.
-%%--------------------------------------------------------------------
-%% Function: handle_call/3
-%% Description: Handling call messages
@@ -3099,14 +3025,14 @@ index 834054a..0000000
-% #state{max_sessions = Max_sess,
-% ets_tid = Tid,
-% max_pipeline_size = Max_pipe_sz,
--% num_cur_sessions = Num} = State)
+-% num_cur_sessions = Num} = State)
-% when Num >= Max ->
-% Reply = find_best_connection(Tid),
-% {reply, sorry_dude_reuse, State};
-
-%% Update max_sessions in #state with supplied value
-handle_call({spawn_connection, _Url, Max_sess, Max_pipe, _}, _From,
-- #state{num_cur_sessions = Num} = State)
+- #state{num_cur_sessions = Num} = State)
- when Num >= Max_sess ->
- State_1 = maybe_create_ets(State),
- Reply = find_best_connection(State_1#state.ets_tid, Max_pipe),
@@ -3120,6 +3046,18 @@ index 834054a..0000000
- ets:insert(Tid, {{1, Pid}, []}),
- {reply, {ok, Pid}, State_1#state{num_cur_sessions = Cur + 1}};
-
+-handle_call(stop, _From, #state{ets_tid = undefined} = State) ->
+- gen_server:reply(_From, ok),
+- {stop, normal, State};
+-
+-handle_call(stop, _From, #state{ets_tid = Tid} = State) ->
+- ets:foldl(fun({{_, Pid}, _}, Acc) ->
+- ibrowse_http_client:stop(Pid),
+- Acc
+- end, [], Tid),
+- gen_server:reply(_From, ok),
+- {stop, normal, State};
+-
-handle_call(Request, _From, State) ->
- Reply = {unknown_request, Request},
- {reply, Reply, State}.
@@ -3214,18 +3152,17 @@ index 834054a..0000000
- State.
diff --git a/src/ibrowse/ibrowse_lib.erl b/src/ibrowse/ibrowse_lib.erl
deleted file mode 100644
-index 6c7b154..0000000
+index 696d0f6..0000000
--- a/src/ibrowse/ibrowse_lib.erl
+++ /dev/null
-@@ -1,399 +0,0 @@
+@@ -1,342 +0,0 @@
-%%% File : ibrowse_lib.erl
-%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
--%%% Description :
+-%%% Description :
-%%% Created : 27 Feb 2004 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%% @doc Module with a few useful functions
-
--module(ibrowse_lib).
---vsn('$Id: ibrowse_lib.erl,v 1.6 2008/03/27 01:35:50 chandrusf Exp $ ').
--author('chandru').
--ifdef(debug).
--compile(export_all).
@@ -3234,37 +3171,23 @@ index 6c7b154..0000000
--include("ibrowse.hrl").
-
--export([
-- get_trace_status/2,
-- do_trace/2,
-- do_trace/3,
-- url_encode/1,
-- decode_rfc822_date/1,
-- status_code/1,
-- dec2hex/2,
-- drv_ue/1,
-- drv_ue/2,
-- encode_base64/1,
-- decode_base64/1,
-- get_value/2,
-- get_value/3,
-- parse_url/1,
-- printable_date/0
-- ]).
+- get_trace_status/2,
+- do_trace/2,
+- do_trace/3,
+- url_encode/1,
+- decode_rfc822_date/1,
+- status_code/1,
+- encode_base64/1,
+- decode_base64/1,
+- get_value/2,
+- get_value/3,
+- parse_url/1,
+- printable_date/0
+- ]).
-
-get_trace_status(Host, Port) ->
- ibrowse:get_config_value({trace, Host, Port}, false).
-
--drv_ue(Str) ->
-- [{port, Port}| _] = ets:lookup(ibrowse_table, port),
-- drv_ue(Str, Port).
--drv_ue(Str, Port) ->
-- case erlang:port_control(Port, 1, Str) of
-- [] ->
-- Str;
-- Res ->
-- Res
-- end.
--
-%% @doc URL-encodes a string based on RFC 1738. Returns a flat list.
-%% @spec url_encode(Str) -> UrlEncodedStr
-%% Str = string()
@@ -3292,10 +3215,10 @@ index 6c7b154..0000000
-
-decode_rfc822_date(String) when is_list(String) ->
- case catch decode_rfc822_date_1(string:tokens(String, ", \t\r\n")) of
-- {'EXIT', _} ->
-- {error, invalid_date};
-- Res ->
-- Res
+- {'EXIT', _} ->
+- {error, invalid_date};
+- Res ->
+- Res
- end.
-
-% TODO: Have to handle the Zone
@@ -3306,15 +3229,15 @@ index 6c7b154..0000000
- MonthI = month_int(Month),
- YearI = list_to_integer(Year),
- TimeTup = case string:tokens(Time, ":") of
-- [H,M] ->
-- {list_to_integer(H),
-- list_to_integer(M),
-- 0};
-- [H,M,S] ->
-- {list_to_integer(H),
-- list_to_integer(M),
-- list_to_integer(S)}
-- end,
+- [H,M] ->
+- {list_to_integer(H),
+- list_to_integer(M),
+- 0};
+- [H,M,S] ->
+- {list_to_integer(H),
+- list_to_integer(M),
+- list_to_integer(S)}
+- end,
- {{YearI,MonthI,DayI}, TimeTup}.
-
-month_int("Jan") -> 1;
@@ -3330,7 +3253,7 @@ index 6c7b154..0000000
-month_int("Nov") -> 11;
-month_int("Dec") -> 12.
-
--%% @doc Given a status code, returns an atom describing the status code.
+-%% @doc Given a status code, returns an atom describing the status code.
-%% @spec status_code(StatusCode::status_code()) -> StatusDescription
-%% status_code() = string() | integer()
-%% StatusDescription = atom()
@@ -3384,100 +3307,30 @@ index 6c7b154..0000000
-status_code(X) when is_list(X) -> status_code(list_to_integer(X));
-status_code(_) -> unknown_status_code.
-
--%% @doc dec2hex taken from gtk.erl in std dist
--%% M = integer() -- number of hex digits required
--%% N = integer() -- the number to represent as hex
--%% @spec dec2hex(M::integer(), N::integer()) -> string()
--dec2hex(M,N) -> dec2hex(M,N,[]).
--
--dec2hex(0,_N,Ack) -> Ack;
--dec2hex(M,N,Ack) -> dec2hex(M-1,N bsr 4,[d2h(N band 15)|Ack]).
--
-%% @doc Implements the base64 encoding algorithm. The output data type matches in the input data type.
-%% @spec encode_base64(In) -> Out
-%% In = string() | binary()
-%% Out = string() | binary()
-encode_base64(List) when is_list(List) ->
-- encode_base64_1(list_to_binary(List));
+- binary_to_list(base64:encode(List));
-encode_base64(Bin) when is_binary(Bin) ->
-- List = encode_base64_1(Bin),
-- list_to_binary(List).
--
--encode_base64_1(<<A:6, B:6, C:6, D:6, Rest/binary>>) ->
-- [int_to_b64(A), int_to_b64(B),
-- int_to_b64(C), int_to_b64(D) | encode_base64_1(Rest)];
--encode_base64_1(<<A:6, B:6, C:4>>) ->
-- [int_to_b64(A), int_to_b64(B), int_to_b64(C bsl 2), $=];
--encode_base64_1(<<A:6, B:2>>) ->
-- [int_to_b64(A), int_to_b64(B bsl 4), $=, $=];
--encode_base64_1(<<>>) ->
-- [].
+- base64:encode(Bin).
-
-%% @doc Implements the base64 decoding algorithm. The output data type matches in the input data type.
-%% @spec decode_base64(In) -> Out | exit({error, invalid_input})
-%% In = string() | binary()
-%% Out = string() | binary()
-decode_base64(List) when is_list(List) ->
-- decode_base64_1(List, []);
+- binary_to_list(base64:decode(List));
-decode_base64(Bin) when is_binary(Bin) ->
-- List = decode_base64_1(binary_to_list(Bin), []),
-- list_to_binary(List).
--
--decode_base64_1([H | T], Acc) when ((H == $\t) or
-- (H == 32) or
-- (H == $\r) or
-- (H == $\n)) ->
-- decode_base64_1(T, Acc);
--
--decode_base64_1([$=, $=], Acc) ->
-- lists:reverse(Acc);
--decode_base64_1([$=, _ | _], _Acc) ->
-- exit({error, invalid_input});
--
--decode_base64_1([A1, B1, $=, $=], Acc) ->
-- A = b64_to_int(A1),
-- B = b64_to_int(B1),
-- Oct1 = (A bsl 2) bor (B bsr 4),
-- decode_base64_1([], [Oct1 | Acc]);
--decode_base64_1([A1, B1, C1, $=], Acc) ->
-- A = b64_to_int(A1),
-- B = b64_to_int(B1),
-- C = b64_to_int(C1),
-- Oct1 = (A bsl 2) bor (B bsr 4),
-- Oct2 = ((B band 16#f) bsl 6) bor (C bsr 2),
-- decode_base64_1([], [Oct2, Oct1 | Acc]);
--decode_base64_1([A1, B1, C1, D1 | T], Acc) ->
-- A = b64_to_int(A1),
-- B = b64_to_int(B1),
-- C = b64_to_int(C1),
-- D = b64_to_int(D1),
-- Oct1 = (A bsl 2) bor (B bsr 4),
-- Oct2 = ((B band 16#f) bsl 4) bor (C bsr 2),
-- Oct3 = ((C band 2#11) bsl 6) bor D,
-- decode_base64_1(T, [Oct3, Oct2, Oct1 | Acc]);
--decode_base64_1([], Acc) ->
-- lists:reverse(Acc).
--
--%% Taken from httpd_util.erl
--int_to_b64(X) when X >= 0, X =< 25 -> X + $A;
--int_to_b64(X) when X >= 26, X =< 51 -> X - 26 + $a;
--int_to_b64(X) when X >= 52, X =< 61 -> X - 52 + $0;
--int_to_b64(62) -> $+;
--int_to_b64(63) -> $/.
--
--%% Taken from httpd_util.erl
--b64_to_int(X) when X >= $A, X =< $Z -> X - $A;
--b64_to_int(X) when X >= $a, X =< $z -> X - $a + 26;
--b64_to_int(X) when X >= $0, X =< $9 -> X - $0 + 52;
--b64_to_int($+) -> 62;
--b64_to_int($/) -> 63.
+- base64:decode(Bin).
-
-get_value(Tag, TVL, DefVal) ->
- case lists:keysearch(Tag, 1, TVL) of
-- false ->
-- DefVal;
-- {value, {_, Val}} ->
-- Val
+- false ->
+- DefVal;
+- {value, {_, Val}} ->
+- Val
- end.
-
-get_value(Tag, TVL) ->
@@ -3490,93 +3343,121 @@ index 6c7b154..0000000
-parse_url([$:, $/, $/ | _], get_protocol, Url, []) ->
- {invalid_uri_1, Url};
-parse_url([$:, $/, $/ | T], get_protocol, Url, TmpAcc) ->
-- Prot = list_to_atom(lists:reverse(TmpAcc)),
-- parse_url(T, get_username,
-- Url#url{protocol = Prot},
-- []);
--parse_url([$/ | T], get_username, Url, TmpAcc) ->
+- Prot = list_to_existing_atom(lists:reverse(TmpAcc)),
+- parse_url(T, get_username,
+- Url#url{protocol = Prot},
+- []);
+-parse_url([H | T], get_username, Url, TmpAcc) when H == $/;
+- H == $? ->
+- Path = case H of
+- $/ ->
+- [$/ | T];
+- $? ->
+- [$/, $? | T]
+- end,
- %% No username/password. No port number
- Url#url{host = lists:reverse(TmpAcc),
-- port = default_port(Url#url.protocol),
-- path = [$/ | T]};
+- port = default_port(Url#url.protocol),
+- path = Path};
-parse_url([$: | T], get_username, Url, TmpAcc) ->
- %% It is possible that no username/password has been
- %% specified. But we'll continue with the assumption that there is
- %% a username/password. If we encounter a '@' later on, there is a
- %% username/password indeed. If we encounter a '/', it was
- %% actually the hostname
-- parse_url(T, get_password,
-- Url#url{username = lists:reverse(TmpAcc)},
-- []);
+- parse_url(T, get_password,
+- Url#url{username = lists:reverse(TmpAcc)},
+- []);
-parse_url([$@ | T], get_username, Url, TmpAcc) ->
-- parse_url(T, get_host,
-- Url#url{username = lists:reverse(TmpAcc),
-- password = ""},
-- []);
+- parse_url(T, get_host,
+- Url#url{username = lists:reverse(TmpAcc),
+- password = ""},
+- []);
-parse_url([$@ | T], get_password, Url, TmpAcc) ->
-- parse_url(T, get_host,
-- Url#url{password = lists:reverse(TmpAcc)},
-- []);
--parse_url([$/ | T], get_password, Url, TmpAcc) ->
+- parse_url(T, get_host,
+- Url#url{password = lists:reverse(TmpAcc)},
+- []);
+-parse_url([H | T], get_password, Url, TmpAcc) when H == $/;
+- H == $? ->
- %% Ok, what we thought was the username/password was the hostname
- %% and portnumber
- #url{username=User} = Url,
- Port = list_to_integer(lists:reverse(TmpAcc)),
+- Path = case H of
+- $/ ->
+- [$/ | T];
+- $? ->
+- [$/, $? | T]
+- end,
- Url#url{host = User,
-- port = Port,
-- username = undefined,
-- password = undefined,
-- path = [$/ | T]};
+- port = Port,
+- username = undefined,
+- password = undefined,
+- path = Path};
-parse_url([$: | T], get_host, #url{} = Url, TmpAcc) ->
-- parse_url(T, get_port,
-- Url#url{host = lists:reverse(TmpAcc)},
-- []);
--parse_url([$/ | T], get_host, #url{protocol=Prot} = Url, TmpAcc) ->
+- parse_url(T, get_port,
+- Url#url{host = lists:reverse(TmpAcc)},
+- []);
+-parse_url([H | T], get_host, #url{protocol=Prot} = Url, TmpAcc) when H == $/;
+- H == $? ->
+- Path = case H of
+- $/ ->
+- [$/ | T];
+- $? ->
+- [$/, $? | T]
+- end,
- Url#url{host = lists:reverse(TmpAcc),
-- port = default_port(Prot),
-- path = [$/ | T]};
--parse_url([$/ | T], get_port, #url{protocol=Prot} = Url, TmpAcc) ->
+- port = default_port(Prot),
+- path = Path};
+-parse_url([H | T], get_port, #url{protocol=Prot} = Url, TmpAcc) when H == $/;
+- H == $? ->
+- Path = case H of
+- $/ ->
+- [$/ | T];
+- $? ->
+- [$/, $? | T]
+- end,
- Port = case TmpAcc of
-- [] ->
-- default_port(Prot);
-- _ ->
-- list_to_integer(lists:reverse(TmpAcc))
-- end,
-- Url#url{port = Port, path = [$/ | T]};
+- [] ->
+- default_port(Prot);
+- _ ->
+- list_to_integer(lists:reverse(TmpAcc))
+- end,
+- Url#url{port = Port, path = Path};
-parse_url([H | T], State, Url, TmpAcc) ->
- parse_url(T, State, Url, [H | TmpAcc]);
-parse_url([], get_host, Url, TmpAcc) when TmpAcc /= [] ->
- Url#url{host = lists:reverse(TmpAcc),
-- port = default_port(Url#url.protocol),
-- path = "/"};
+- port = default_port(Url#url.protocol),
+- path = "/"};
-parse_url([], get_username, Url, TmpAcc) when TmpAcc /= [] ->
- Url#url{host = lists:reverse(TmpAcc),
-- port = default_port(Url#url.protocol),
-- path = "/"};
+- port = default_port(Url#url.protocol),
+- path = "/"};
-parse_url([], get_port, #url{protocol=Prot} = Url, TmpAcc) ->
- Port = case TmpAcc of
-- [] ->
-- default_port(Prot);
-- _ ->
-- list_to_integer(lists:reverse(TmpAcc))
-- end,
-- Url#url{port = Port,
-- path = "/"};
+- [] ->
+- default_port(Prot);
+- _ ->
+- list_to_integer(lists:reverse(TmpAcc))
+- end,
+- Url#url{port = Port,
+- path = "/"};
-parse_url([], get_password, Url, TmpAcc) ->
- %% Ok, what we thought was the username/password was the hostname
- %% and portnumber
- #url{username=User} = Url,
- Port = case TmpAcc of
-- [] ->
-- default_port(Url#url.protocol);
-- _ ->
-- list_to_integer(lists:reverse(TmpAcc))
-- end,
+- [] ->
+- default_port(Url#url.protocol);
+- _ ->
+- list_to_integer(lists:reverse(TmpAcc))
+- end,
- Url#url{host = User,
-- port = Port,
-- username = undefined,
-- password = undefined,
-- path = "/"};
+- port = Port,
+- username = undefined,
+- password = undefined,
+- path = "/"};
-parse_url([], State, Url, TmpAcc) ->
- {invalid_uri_2, State, Url, TmpAcc}.
-
@@ -3607,32 +3488,30 @@ index 6c7b154..0000000
--ifdef(DEBUG).
-do_trace(_, Fmt, Args) ->
- io:format("~s -- (~s) - "++Fmt,
-- [printable_date(),
-- get(ibrowse_trace_token) | Args]).
+- [printable_date(),
+- get(ibrowse_trace_token) | Args]).
--else.
-do_trace(true, Fmt, Args) ->
- io:format("~s -- (~s) - "++Fmt,
-- [printable_date(),
-- get(ibrowse_trace_token) | Args]);
+- [printable_date(),
+- get(ibrowse_trace_token) | Args]);
-do_trace(_, _, _) ->
- ok.
--endif.
diff --git a/src/ibrowse/ibrowse_sup.erl b/src/ibrowse/ibrowse_sup.erl
deleted file mode 100644
-index 1b9b863..0000000
+index ace33d1..0000000
--- a/src/ibrowse/ibrowse_sup.erl
+++ /dev/null
-@@ -1,65 +0,0 @@
+@@ -1,63 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : ibrowse_sup.erl
-%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
--%%% Description :
+-%%% Description :
-%%%
-%%% Created : 15 Oct 2003 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%%%-------------------------------------------------------------------
--module(ibrowse_sup).
---vsn('$Id: ibrowse_sup.erl,v 1.1 2005/05/05 22:28:28 chandrusf Exp $ ').
--
--behaviour(supervisor).
-%%--------------------------------------------------------------------
-%% Include files
@@ -3678,7 +3557,7 @@ index 1b9b863..0000000
-%% Func: init/1
-%% Returns: {ok, {SupFlags, [ChildSpec]}} |
-%% ignore |
--%% {error, Reason}
+-%% {error, Reason}
-%%--------------------------------------------------------------------
-init([]) ->
- AChild = {ibrowse,{ibrowse,start_link,[]},
@@ -3690,17 +3569,16 @@ index 1b9b863..0000000
-%%====================================================================
diff --git a/src/ibrowse/ibrowse_test.erl b/src/ibrowse/ibrowse_test.erl
deleted file mode 100644
-index 3dc66ec..0000000
+index b8e0a4a..0000000
--- a/src/ibrowse/ibrowse_test.erl
+++ /dev/null
-@@ -1,377 +0,0 @@
+@@ -1,519 +0,0 @@
-%%% File : ibrowse_test.erl
-%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-%%% Description : Test ibrowse
-%%% Created : 14 Oct 2003 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi at t-mobile.co.uk>
-
--module(ibrowse_test).
---vsn('$Id: ibrowse_test.erl,v 1.4 2009/07/01 22:43:19 chandrusf Exp $ ').
--export([
- load_test/3,
- send_reqs_1/3,
@@ -3714,9 +3592,11 @@ index 3dc66ec..0000000
- ue_test/1,
- verify_chunked_streaming/0,
- verify_chunked_streaming/1,
+- test_chunked_streaming_once/0,
- i_do_async_req_list/4,
- test_stream_once/3,
-- test_stream_once/4
+- test_stream_once/4,
+- test_20122010/0
- ]).
-
-test_stream_once(Url, Method, Options) ->
@@ -3889,6 +3769,7 @@ index 3dc66ec..0000000
- {"http://www.google.co.uk", get},
- {"http://www.google.com", get},
- {"http://www.google.com", options},
+- {"https://mail.google.com", get},
- {"http://www.sun.com", get},
- {"http://www.oracle.com", get},
- {"http://www.bbc.co.uk", get},
@@ -3912,16 +3793,23 @@ index 3dc66ec..0000000
- {"http://jigsaw.w3.org/HTTP/300/", get},
- {"http://jigsaw.w3.org/HTTP/Basic/", get, [{basic_auth, {"guest", "guest"}}]},
- {"http://jigsaw.w3.org/HTTP/CL/", get},
-- {"http://www.httpwatch.com/httpgallery/chunked/", get}
+- {"http://www.httpwatch.com/httpgallery/chunked/", get},
+- {"https://github.com", get, [{ssl_options, [{depth, 2}]}]},
+- {local_test_fun, test_20122010, []}
- ]).
-
-unit_tests() ->
- unit_tests([]).
-
-unit_tests(Options) ->
+- application:start(crypto),
+- application:start(public_key),
+- application:start(ssl),
+- (catch ibrowse_test_server:start_server(8181, tcp)),
+- ibrowse:start(),
- Options_1 = Options ++ [{connect_timeout, 5000}],
- {Pid, Ref} = erlang:spawn_monitor(?MODULE, unit_tests_1, [self(), Options_1]),
-- receive
+- receive
- {done, Pid} ->
- ok;
- {'DOWN', Ref, _, _, Info} ->
@@ -3932,7 +3820,9 @@ index 3dc66ec..0000000
- end.
-
-unit_tests_1(Parent, Options) ->
-- lists:foreach(fun({Url, Method}) ->
+- lists:foreach(fun({local_test_fun, Fun_name, Args}) ->
+- execute_req(local_test_fun, Fun_name, Args);
+- ({Url, Method}) ->
- execute_req(Url, Method, Options);
- ({Url, Method, X_Opts}) ->
- execute_req(Url, Method, X_Opts ++ Options)
@@ -3943,19 +3833,45 @@ index 3dc66ec..0000000
- verify_chunked_streaming([]).
-
-verify_chunked_streaming(Options) ->
+- io:format("~nVerifying that chunked streaming is working...~n", []),
- Url = "http://www.httpwatch.com/httpgallery/chunked/",
-- io:format("URL: ~s~n", [Url]),
-- io:format("Fetching data without streaming...~n", []),
+- io:format(" URL: ~s~n", [Url]),
+- io:format(" Fetching data without streaming...~n", []),
- Result_without_streaming = ibrowse:send_req(
- Url, [], get, [],
- [{response_format, binary} | Options]),
-- io:format("Fetching data with streaming as list...~n", []),
+- io:format(" Fetching data with streaming as list...~n", []),
- Async_response_list = do_async_req_list(
- Url, get, [{response_format, list} | Options]),
-- io:format("Fetching data with streaming as binary...~n", []),
+- io:format(" Fetching data with streaming as binary...~n", []),
- Async_response_bin = do_async_req_list(
- Url, get, [{response_format, binary} | Options]),
-- compare_responses(Result_without_streaming, Async_response_list, Async_response_bin).
+- io:format(" Fetching data with streaming as binary, {active, once}...~n", []),
+- Async_response_bin_once = do_async_req_list(
+- Url, get, [once, {response_format, binary} | Options]),
+- Res1 = compare_responses(Result_without_streaming, Async_response_list, Async_response_bin),
+- Res2 = compare_responses(Result_without_streaming, Async_response_list, Async_response_bin_once),
+- case {Res1, Res2} of
+- {success, success} ->
+- io:format(" Chunked streaming working~n", []);
+- _ ->
+- ok
+- end.
+-
+-test_chunked_streaming_once() ->
+- test_chunked_streaming_once([]).
+-
+-test_chunked_streaming_once(Options) ->
+- io:format("~nTesting chunked streaming with the {stream_to, {Pid, once}} option...~n", []),
+- Url = "http://www.httpwatch.com/httpgallery/chunked/",
+- io:format(" URL: ~s~n", [Url]),
+- io:format(" Fetching data with streaming as binary, {active, once}...~n", []),
+- case do_async_req_list(Url, get, [once, {response_format, binary} | Options]) of
+- {ok, _, _, _} ->
+- io:format(" Success!~n", []);
+- Err ->
+- io:format(" Fail: ~p~n", [Err])
+- end.
-
-compare_responses({ok, St_code, _, Body}, {ok, St_code, _, Body}, {ok, St_code, _, Body}) ->
- success;
@@ -3989,9 +3905,9 @@ index 3dc66ec..0000000
-
-do_async_req_list(Url, Method, Options) ->
- {Pid,_} = erlang:spawn_monitor(?MODULE, i_do_async_req_list,
-- [self(), Url, Method,
+- [self(), Url, Method,
- Options ++ [{stream_chunk_size, 1000}]]),
-- io:format("Spawned process ~p~n", [Pid]),
+-%% io:format("Spawned process ~p~n", [Pid]),
- wait_for_resp(Pid).
-
-wait_for_resp(Pid) ->
@@ -4008,33 +3924,60 @@ index 3dc66ec..0000000
- Msg ->
- io:format("Recvd unknown message: ~p~n", [Msg]),
- wait_for_resp(Pid)
-- after 10000 ->
+- after 100000 ->
- {error, timeout}
- end.
-
-i_do_async_req_list(Parent, Url, Method, Options) ->
-- Res = ibrowse:send_req(Url, [], Method, [], [{stream_to, self()} | Options]),
+- Options_1 = case lists:member(once, Options) of
+- true ->
+- [{stream_to, {self(), once}} | (Options -- [once])];
+- false ->
+- [{stream_to, self()} | Options]
+- end,
+- Res = ibrowse:send_req(Url, [], Method, [], Options_1),
- case Res of
- {ibrowse_req_id, Req_id} ->
-- Result = wait_for_async_resp(Req_id, undefined, undefined, []),
+- Result = wait_for_async_resp(Req_id, Options, undefined, undefined, []),
- Parent ! {async_result, self(), Result};
- Err ->
- Parent ! {async_result, self(), Err}
- end.
-
--wait_for_async_resp(Req_id, Acc_Stat_code, Acc_Headers, Body) ->
+-wait_for_async_resp(Req_id, Options, Acc_Stat_code, Acc_Headers, Body) ->
- receive
- {ibrowse_async_headers, Req_id, StatCode, Headers} ->
-- wait_for_async_resp(Req_id, StatCode, Headers, Body);
+- %% io:format("Recvd headers...~n", []),
+- maybe_stream_next(Req_id, Options),
+- wait_for_async_resp(Req_id, Options, StatCode, Headers, Body);
- {ibrowse_async_response_end, Req_id} ->
+- %% io:format("Recvd end of response.~n", []),
- Body_1 = list_to_binary(lists:reverse(Body)),
- {ok, Acc_Stat_code, Acc_Headers, Body_1};
- {ibrowse_async_response, Req_id, Data} ->
-- wait_for_async_resp(Req_id, Acc_Stat_code, Acc_Headers, [Data | Body]);
+- maybe_stream_next(Req_id, Options),
+- %% io:format("Recvd data...~n", []),
+- wait_for_async_resp(Req_id, Options, Acc_Stat_code, Acc_Headers, [Data | Body]);
+- {ibrowse_async_response, Req_id, {error, _} = Err} ->
+- {ok, Acc_Stat_code, Acc_Headers, Err};
- Err ->
- {ok, Acc_Stat_code, Acc_Headers, Err}
+- after 10000 ->
+- {timeout, Acc_Stat_code, Acc_Headers, Body}
+- end.
+-
+-maybe_stream_next(Req_id, Options) ->
+- case lists:member(once, Options) of
+- true ->
+- ibrowse:stream_next(Req_id);
+- false ->
+- ok
- end.
-
+-execute_req(local_test_fun, Method, Args) ->
+- io:format(" ~-54.54w: ", [Method]),
+- Result = (catch apply(?MODULE, Method, Args)),
+- io:format("~p~n", [Result]);
-execute_req(Url, Method, Options) ->
- io:format("~7.7w, ~50.50s: ", [Method, Url]),
- Result = (catch ibrowse:send_req(Url, [], Method, [], Options)),
@@ -4042,7 +3985,7 @@ index 3dc66ec..0000000
- {ok, SCode, _H, _B} ->
- io:format("Status code: ~p~n", [SCode]);
- Err ->
-- io:format("Err -> ~p~n", [Err])
+- io:format("~p~n", [Err])
- end.
-
-drv_ue_test() ->
@@ -4071,19 +4014,97 @@ index 3dc66ec..0000000
-log_msg(Fmt, Args) ->
- io:format("~s -- " ++ Fmt,
- [ibrowse_lib:printable_date() | Args]).
+-
+-%%------------------------------------------------------------------------------
+-%%
+-%%------------------------------------------------------------------------------
+-
+-test_20122010() ->
+- {ok, Pid} = ibrowse:spawn_worker_process("http://localhost:8181"),
+- Expected_resp = <<"1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40-41-42-43-44-45-46-47-48-49-50-51-52-53-54-55-56-57-58-59-60-61-62-63-64-65-66-67-68-69-70-71-72-73-74-75-76-77-78-79-80-81-82-83-84-85-86-87-88-89-90-91-92-93-94-95-96-97-98-99-100">>,
+- Test_parent = self(),
+- Fun = fun() ->
+- do_test_20122010(Pid, Expected_resp, Test_parent)
+- end,
+- Pids = [erlang:spawn_monitor(Fun) || _ <- lists:seq(1,10)],
+- wait_for_workers(Pids).
+-
+-wait_for_workers([{Pid, _Ref} | Pids]) ->
+- receive
+- {Pid, success} ->
+- wait_for_workers(Pids)
+- after 5000 ->
+- test_failed
+- end;
+-wait_for_workers([]) ->
+- success.
+-
+-do_test_20122010(Pid, Expected_resp, Test_parent) ->
+- {ibrowse_req_id, Req_id} = ibrowse:send_req_direct(
+- Pid,
+- "http://localhost:8181/ibrowse_stream_once_chunk_pipeline_test",
+- [], get, [],
+- [{stream_to, {self(), once}},
+- {include_ibrowse_req_id, true}]),
+- do_trace("~p -- sent request ~1000.p~n", [self(), Req_id]),
+- Req_id_str = lists:flatten(io_lib:format("~1000.p",[Req_id])),
+- receive
+- {ibrowse_async_headers, Req_id, "200", Headers} ->
+- case lists:keysearch("x-ibrowse-request-id", 1, Headers) of
+- {value, {_, Req_id_str}} ->
+- ok;
+- {value, {_, Req_id_1}} ->
+- do_trace("~p -- Sent req-id: ~1000.p. Recvd: ~1000.p~n",
+- [self(), Req_id, Req_id_1]),
+- exit(req_id_mismatch)
+- end
+- after 5000 ->
+- do_trace("~p -- response headers not received~n", [self()]),
+- exit({timeout, test_failed})
+- end,
+- do_trace("~p -- response headers received~n", [self()]),
+- ok = ibrowse:stream_next(Req_id),
+- case do_test_20122010_1(Expected_resp, Req_id, []) of
+- true ->
+- Test_parent ! {self(), success};
+- false ->
+- Test_parent ! {self(), failed}
+- end.
+-
+-do_test_20122010_1(Expected_resp, Req_id, Acc) ->
+- receive
+- {ibrowse_async_response, Req_id, Body_part} ->
+- ok = ibrowse:stream_next(Req_id),
+- do_test_20122010_1(Expected_resp, Req_id, [Body_part | Acc]);
+- {ibrowse_async_response_end, Req_id} ->
+- Acc_1 = list_to_binary(lists:reverse(Acc)),
+- Result = Acc_1 == Expected_resp,
+- do_trace("~p -- End of response. Result: ~p~n", [self(), Result]),
+- Result
+- after 1000 ->
+- exit({timeout, test_failed})
+- end.
+-
+-do_trace(Fmt, Args) ->
+- do_trace(get(my_trace_flag), Fmt, Args).
+-
+-do_trace(true, Fmt, Args) ->
+- io:format("~s -- " ++ Fmt, [ibrowse_lib:printable_date() | Args]);
+-do_trace(_, _, _) ->
+- ok.
diff --git a/test/etap/test_util.erl.in b/test/etap/test_util.erl.in
-index 948958c..2650fbb 100644
+index c57d7a8..1b9e434 100644
--- a/test/etap/test_util.erl.in
+++ b/test/etap/test_util.erl.in
@@ -22,7 +22,7 @@ builddir() ->
"@abs_top_builddir@".
init_code_path() ->
-- Paths = ["couchdb", "ibrowse"],
-+ Paths = ["couchdb"],
+- Paths = ["couchdb", "ibrowse", "mochiweb"],
++ Paths = ["couchdb", "mochiweb"],
lists:foreach(fun(Name) ->
code:add_pathz(filename:join([builddir(), "src", Name]))
end, Paths).
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0005-Remove-bundled-mochiweb-library.patch b/couchdb-0008-Remove-bundled-mochiweb-library.patch
similarity index 93%
rename from couchdb-0005-Remove-bundled-mochiweb-library.patch
rename to couchdb-0008-Remove-bundled-mochiweb-library.patch
index dfd1856..ce1471d 100644
--- a/couchdb-0005-Remove-bundled-mochiweb-library.patch
+++ b/couchdb-0008-Remove-bundled-mochiweb-library.patch
@@ -1,21 +1,19 @@
-From fd2a4e300e7c56608402cd851a73d5824be02fdb Mon Sep 17 00:00:00 2001
+From 7b13eb4a872f188ca2581986c998963784b0aa09 Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
-Date: Wed, 14 Jul 2010 18:01:45 +0400
-Subject: [PATCH 05/13] Remove bundled mochiweb library
+Date: Sun, 13 Feb 2011 14:48:47 +0300
+Subject: [PATCH 08/13] Remove bundled mochiweb library
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
- configure | 3 -
configure.ac | 1 -
src/Makefile.am | 2 +-
- src/Makefile.in | 2 +-
src/mochiweb/Makefile.am | 80 ---
- src/mochiweb/Makefile.in | 515 ------------------
src/mochiweb/mochifmt.erl | 426 ---------------
src/mochiweb/mochifmt_records.erl | 30 -
src/mochiweb/mochifmt_std.erl | 23 -
src/mochiweb/mochihex.erl | 75 ---
src/mochiweb/mochijson.erl | 528 ------------------
- src/mochiweb/mochijson2.erl | 660 -----------------------
+ src/mochiweb/mochijson2.erl | 676 -----------------------
src/mochiweb/mochinum.erl | 289 ----------
src/mochiweb/mochiweb.app.in | 32 --
src/mochiweb/mochiweb.erl | 110 ----
@@ -35,9 +33,8 @@ Subject: [PATCH 05/13] Remove bundled mochiweb library
src/mochiweb/mochiweb_util.erl | 859 -----------------------------
src/mochiweb/reloader.erl | 123 -----
test/etap/test_util.erl.in | 2 +-
- 31 files changed, 3 insertions(+), 7464 deletions(-)
+ 28 files changed, 2 insertions(+), 6961 deletions(-)
delete mode 100644 src/mochiweb/Makefile.am
- delete mode 100644 src/mochiweb/Makefile.in
delete mode 100644 src/mochiweb/mochifmt.erl
delete mode 100644 src/mochiweb/mochifmt_records.erl
delete mode 100644 src/mochiweb/mochifmt_std.erl
@@ -63,62 +60,28 @@ Subject: [PATCH 05/13] Remove bundled mochiweb library
delete mode 100644 src/mochiweb/mochiweb_util.erl
delete mode 100644 src/mochiweb/reloader.erl
-diff --git a/configure b/configure
-index a8d077e..e82813c 100755
---- a/configure
-+++ b/configure
-@@ -12265,8 +12265,6 @@ ac_config_files="$ac_config_files src/couchdb/priv/Makefile"
-
- ac_config_files="$ac_config_files src/ibrowse/Makefile"
-
--ac_config_files="$ac_config_files src/mochiweb/Makefile"
--
- ac_config_files="$ac_config_files test/Makefile"
-
- ac_config_files="$ac_config_files test/bench/Makefile"
-@@ -13290,7 +13288,6 @@ do
- "src/couchdb/Makefile") CONFIG_FILES="$CONFIG_FILES src/couchdb/Makefile" ;;
- "src/couchdb/priv/Makefile") CONFIG_FILES="$CONFIG_FILES src/couchdb/priv/Makefile" ;;
- "src/ibrowse/Makefile") CONFIG_FILES="$CONFIG_FILES src/ibrowse/Makefile" ;;
-- "src/mochiweb/Makefile") CONFIG_FILES="$CONFIG_FILES src/mochiweb/Makefile" ;;
- "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
- "test/bench/Makefile") CONFIG_FILES="$CONFIG_FILES test/bench/Makefile" ;;
- "test/etap/Makefile") CONFIG_FILES="$CONFIG_FILES test/etap/Makefile" ;;
diff --git a/configure.ac b/configure.ac
-index 7e25bc2..157d8c0 100644
+index 4b2c94e..9c10cf7 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -389,7 +389,6 @@ AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
+@@ -404,7 +404,6 @@ AC_CONFIG_FILES([src/Makefile])
+ AC_CONFIG_FILES([src/couchdb/couch.app.tpl])
AC_CONFIG_FILES([src/couchdb/Makefile])
AC_CONFIG_FILES([src/couchdb/priv/Makefile])
- AC_CONFIG_FILES([src/ibrowse/Makefile])
-AC_CONFIG_FILES([src/mochiweb/Makefile])
AC_CONFIG_FILES([test/Makefile])
AC_CONFIG_FILES([test/bench/Makefile])
AC_CONFIG_FILES([test/etap/Makefile])
diff --git a/src/Makefile.am b/src/Makefile.am
-index 19a5d20..5a6646f 100644
+index d50341a..753b177 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,4 +10,4 @@
## License for the specific language governing permissions and limitations under
## the License.
--SUBDIRS = couchdb ibrowse mochiweb
-+SUBDIRS = couchdb ibrowse
-diff --git a/src/Makefile.in b/src/Makefile.in
-index ae1b828..2d11fc8 100644
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -248,7 +248,7 @@ version_minor = @version_minor@
- version_release = @version_release@
- version_revision = @version_revision@
- version_stage = @version_stage@
--SUBDIRS = couchdb ibrowse mochiweb
-+SUBDIRS = couchdb ibrowse
- all: all-recursive
-
- .SUFFIXES:
+-SUBDIRS = couchdb mochiweb
++SUBDIRS = couchdb
diff --git a/src/mochiweb/Makefile.am b/src/mochiweb/Makefile.am
deleted file mode 100644
index c191abf..0000000
@@ -205,527 +168,6 @@ index c191abf..0000000
-
-%.beam: %.erl
- $(ERLC) $(ERLC_FLAGS) $<
-diff --git a/src/mochiweb/Makefile.in b/src/mochiweb/Makefile.in
-deleted file mode 100644
-index 92f0acc..0000000
---- a/src/mochiweb/Makefile.in
-+++ /dev/null
-@@ -1,515 +0,0 @@
--# Makefile.in generated by automake 1.11 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
--# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
--# Inc.
--# This Makefile.in is free software; the Free Software Foundation
--# gives unlimited permission to copy and/or distribute it,
--# with or without modifications, as long as this notice is preserved.
--
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
--# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
--# PARTICULAR PURPOSE.
--
-- at SET_MAKE@
--
--VPATH = @srcdir@
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@PACKAGE@
--am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
--install_sh_DATA = $(install_sh) -c -m 644
--install_sh_PROGRAM = $(install_sh) -c
--install_sh_SCRIPT = $(install_sh) -c
--INSTALL_HEADER = $(INSTALL_DATA)
--transform = $(program_transform_name)
--NORMAL_INSTALL = :
--PRE_INSTALL = :
--POST_INSTALL = :
--NORMAL_UNINSTALL = :
--PRE_UNINSTALL = :
--POST_UNINSTALL = :
--build_triplet = @build@
--host_triplet = @host@
--subdir = src/mochiweb
--DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_curl.m4 \
-- $(top_srcdir)/m4/ac_check_icu.m4 $(top_srcdir)/m4/libtool.m4 \
-- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-- $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-- $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--SOURCES =
--DIST_SOURCES =
--am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
--am__vpath_adj = case $$p in \
-- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-- *) f=$$p;; \
-- esac;
--am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
--am__install_max = 40
--am__nobase_strip_setup = \
-- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
--am__nobase_strip = \
-- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
--am__nobase_list = $(am__nobase_strip_setup); \
-- for p in $$list; do echo "$$p $$p"; done | \
-- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-- if (++n[$$2] == $(am__install_max)) \
-- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-- END { for (dir in files) print dir, files[dir] }'
--am__base_list = \
-- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
--am__installdirs = "$(DESTDIR)$(mochiwebebindir)"
--DATA = $(mochiwebebin_DATA)
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AR = @AR@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CURL_CFLAGS = @CURL_CFLAGS@
--CURL_CONFIG = @CURL_CONFIG@
--CURL_LDFLAGS = @CURL_LDFLAGS@
--CURL_LIBS = @CURL_LIBS@
--CYGPATH_W = @CYGPATH_W@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--ERL = @ERL@
--ERLC = @ERLC@
--ERLC_FLAGS = @ERLC_FLAGS@
--EXEEXT = @EXEEXT@
--FGREP = @FGREP@
--FLAGS = @FLAGS@
--GREP = @GREP@
--HELP2MAN_EXECUTABLE = @HELP2MAN_EXECUTABLE@
--ICU_CFLAGS = @ICU_CFLAGS@
--ICU_CONFIG = @ICU_CONFIG@
--ICU_CXXFLAGS = @ICU_CXXFLAGS@
--ICU_LIBS = @ICU_LIBS@
--ICU_LOCAL_BIN = @ICU_LOCAL_BIN@
--ICU_LOCAL_CFLAGS = @ICU_LOCAL_CFLAGS@
--ICU_LOCAL_LDFLAGS = @ICU_LOCAL_LDFLAGS@
--INNO_COMPILER_EXECUTABLE = @INNO_COMPILER_EXECUTABLE@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--JSLIB = @JSLIB@
--JS_LIB_BASE = @JS_LIB_BASE@
--JS_LIB_BINARY = @JS_LIB_BINARY@
--JS_LIB_DIR = @JS_LIB_DIR@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAKEINFO = @MAKEINFO@
--MKDIR_P = @MKDIR_P@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--RANLIB = @RANLIB@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--VERSION = @VERSION@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--am__include = @am__include@
--am__leading_dot = @am__leading_dot@
--am__quote = @am__quote@
--am__tar = @am__tar@
--am__untar = @am__untar@
--bindir = @bindir@
--bug_uri = @bug_uri@
--build = @build@
--build_alias = @build_alias@
--build_cpu = @build_cpu@
--build_os = @build_os@
--build_vendor = @build_vendor@
--builddir = @builddir@
--datadir = @datadir@
--datarootdir = @datarootdir@
--docdir = @docdir@
--dvidir = @dvidir@
--exec_prefix = @exec_prefix@
--host = @host@
--host_alias = @host_alias@
--host_cpu = @host_cpu@
--host_os = @host_os@
--host_vendor = @host_vendor@
--htmldir = @htmldir@
--includedir = @includedir@
--infodir = @infodir@
--initdir = @initdir@
--install_sh = @install_sh@
--launchddir = @launchddir@
--libdir = @libdir@
--libexecdir = @libexecdir@
--localconfdir = @localconfdir@
--localdatadir = @localdatadir@
--localdocdir = @localdocdir@
--localedir = @localedir@
--localerlanglibdir = @localerlanglibdir@
--locallibbindir = @locallibbindir@
--locallibdir = @locallibdir@
--localstatedir = @localstatedir@
--localstatelibdir = @localstatelibdir@
--localstatelogdir = @localstatelogdir@
--localstaterundir = @localstaterundir@
--lt_ECHO = @lt_ECHO@
--mandir = @mandir@
--mkdir_p = @mkdir_p@
--msvc_redist_dir = @msvc_redist_dir@
--msvc_redist_name = @msvc_redist_name@
--oldincludedir = @oldincludedir@
--openssl_bin_dir = @openssl_bin_dir@
--package_author_address = @package_author_address@
--package_author_name = @package_author_name@
--package_identifier = @package_identifier@
--package_name = @package_name@
--package_tarname = @package_tarname@
--pdfdir = @pdfdir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--version = @version@
--version_major = @version_major@
--version_minor = @version_minor@
--version_release = @version_release@
--version_revision = @version_revision@
--version_stage = @version_stage@
--mochiwebebindir = $(localerlanglibdir)/mochiweb-r113/ebin
--mochiweb_file_collection = \
-- mochifmt.erl \
-- mochifmt_records.erl \
-- mochifmt_std.erl \
-- mochihex.erl \
-- mochijson.erl \
-- mochijson2.erl \
-- mochinum.erl \
-- mochiweb.app.in \
-- mochiweb.erl \
-- mochiweb_app.erl \
-- mochiweb_charref.erl \
-- mochiweb_cookies.erl \
-- mochiweb_echo.erl \
-- mochiweb_headers.erl \
-- mochiweb_html.erl \
-- mochiweb_http.erl \
-- mochiweb_multipart.erl \
-- mochiweb_request.erl \
-- mochiweb_response.erl \
-- mochiweb_skel.erl \
-- mochiweb_socket_server.erl \
-- mochiweb_sup.erl \
-- mochiweb_util.erl \
-- reloader.erl
--
--mochiwebebin_make_generated_file_list = \
-- mochifmt.beam \
-- mochifmt_records.beam \
-- mochifmt_std.beam \
-- mochihex.beam \
-- mochijson.beam \
-- mochijson2.beam \
-- mochinum.beam \
-- mochiweb.app \
-- mochiweb.beam \
-- mochiweb_app.beam \
-- mochiweb_charref.beam \
-- mochiweb_cookies.beam \
-- mochiweb_echo.beam \
-- mochiweb_headers.beam \
-- mochiweb_html.beam \
-- mochiweb_http.beam \
-- mochiweb_multipart.beam \
-- mochiweb_request.beam \
-- mochiweb_response.beam \
-- mochiweb_skel.beam \
-- mochiweb_socket_server.beam \
-- mochiweb_sup.beam \
-- mochiweb_util.beam \
-- reloader.beam
--
--mochiwebebin_DATA = \
-- $(mochiwebebin_make_generated_file_list)
--
--EXTRA_DIST = \
-- $(mochiweb_file_collection)
--
--CLEANFILES = \
-- $(mochiwebebin_make_generated_file_list)
--
--all: all-am
--
--.SUFFIXES:
--$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
-- @for dep in $?; do \
-- case '$(am__configure_deps)' in \
-- *$$dep*) \
-- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-- && { if test -f $@; then exit 0; else break; fi; }; \
-- exit 1;; \
-- esac; \
-- done; \
-- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/mochiweb/Makefile'; \
-- $(am__cd) $(top_srcdir) && \
-- $(AUTOMAKE) --foreign src/mochiweb/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-- @case '$?' in \
-- *config.status*) \
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-- *) \
-- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-- esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure: $(am__configure_deps)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4): $(am__aclocal_m4_deps)
-- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--mostlyclean-libtool:
-- -rm -f *.lo
--
--clean-libtool:
-- -rm -rf .libs _libs
--install-mochiwebebinDATA: $(mochiwebebin_DATA)
-- @$(NORMAL_INSTALL)
-- test -z "$(mochiwebebindir)" || $(MKDIR_P) "$(DESTDIR)$(mochiwebebindir)"
-- @list='$(mochiwebebin_DATA)'; test -n "$(mochiwebebindir)" || list=; \
-- for p in $$list; do \
-- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-- echo "$$d$$p"; \
-- done | $(am__base_list) | \
-- while read files; do \
-- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(mochiwebebindir)'"; \
-- $(INSTALL_DATA) $$files "$(DESTDIR)$(mochiwebebindir)" || exit $$?; \
-- done
--
--uninstall-mochiwebebinDATA:
-- @$(NORMAL_UNINSTALL)
-- @list='$(mochiwebebin_DATA)'; test -n "$(mochiwebebindir)" || list=; \
-- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-- test -n "$$files" || exit 0; \
-- echo " ( cd '$(DESTDIR)$(mochiwebebindir)' && rm -f" $$files ")"; \
-- cd "$(DESTDIR)$(mochiwebebindir)" && rm -f $$files
--tags: TAGS
--TAGS:
--
--ctags: CTAGS
--CTAGS:
--
--
--distdir: $(DISTFILES)
-- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-- list='$(DISTFILES)'; \
-- dist_files=`for file in $$list; do echo $$file; done | \
-- sed -e "s|^$$srcdirstrip/||;t" \
-- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-- case $$dist_files in \
-- */*) $(MKDIR_P) `echo "$$dist_files" | \
-- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-- sort -u` ;; \
-- esac; \
-- for file in $$dist_files; do \
-- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-- if test -d $$d/$$file; then \
-- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-- if test -d "$(distdir)/$$file"; then \
-- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-- fi; \
-- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-- fi; \
-- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-- else \
-- test -f "$(distdir)/$$file" \
-- || cp -p $$d/$$file "$(distdir)/$$file" \
-- || exit 1; \
-- fi; \
-- done
--check-am: all-am
--check: check-am
--all-am: Makefile $(DATA)
--installdirs:
-- for dir in "$(DESTDIR)$(mochiwebebindir)"; do \
-- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-- done
--install: install-am
--install-exec: install-exec-am
--install-data: install-data-am
--uninstall: uninstall-am
--
--install-am: all-am
-- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
--
--installcheck: installcheck-am
--install-strip:
-- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-- `test -z '$(STRIP)' || \
-- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
--mostlyclean-generic:
--
--clean-generic:
-- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
--
--distclean-generic:
-- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
-- @echo "This command is intended for maintainers to use"
-- @echo "it deletes files that may require special tools to rebuild."
--clean: clean-am
--
--clean-am: clean-generic clean-libtool mostlyclean-am
--
--distclean: distclean-am
-- -rm -f Makefile
--distclean-am: clean-am distclean-generic
--
--dvi: dvi-am
--
--dvi-am:
--
--html: html-am
--
--html-am:
--
--info: info-am
--
--info-am:
--
--install-data-am: install-mochiwebebinDATA
--
--install-dvi: install-dvi-am
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-am
--
--install-html-am:
--
--install-info: install-info-am
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-am
--
--install-pdf-am:
--
--install-ps: install-ps-am
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-am
-- -rm -f Makefile
--maintainer-clean-am: distclean-am maintainer-clean-generic
--
--mostlyclean: mostlyclean-am
--
--mostlyclean-am: mostlyclean-generic mostlyclean-libtool
--
--pdf: pdf-am
--
--pdf-am:
--
--ps: ps-am
--
--ps-am:
--
--uninstall-am: uninstall-mochiwebebinDATA
--
--.MAKE: install-am install-strip
--
--.PHONY: all all-am check check-am clean clean-generic clean-libtool \
-- distclean distclean-generic distclean-libtool distdir dvi \
-- dvi-am html html-am info info-am install install-am \
-- install-data install-data-am install-dvi install-dvi-am \
-- install-exec install-exec-am install-html install-html-am \
-- install-info install-info-am install-man \
-- install-mochiwebebinDATA install-pdf install-pdf-am install-ps \
-- install-ps-am install-strip installcheck installcheck-am \
-- installdirs maintainer-clean maintainer-clean-generic \
-- mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
-- ps ps-am uninstall uninstall-am uninstall-mochiwebebinDATA
--
--
--%.app: %.app.in
-- cp $< $@
--
--%.beam: %.erl
-- $(ERLC) $(ERLC_FLAGS) $<
--
--# Tell versions [3.59,3.63) of GNU make to not export all variables.
--# Otherwise a system limit (for SysV at least) may be exceeded.
--.NOEXPORT:
diff --git a/src/mochiweb/mochifmt.erl b/src/mochiweb/mochifmt.erl
deleted file mode 100644
index da0a133..0000000
@@ -1840,10 +1282,10 @@ index 74695a7..0000000
- ].
diff --git a/src/mochiweb/mochijson2.erl b/src/mochiweb/mochijson2.erl
deleted file mode 100644
-index 111c37b..0000000
+index 1ed2b88..0000000
--- a/src/mochiweb/mochijson2.erl
+++ /dev/null
-@@ -1,660 +0,0 @@
+@@ -1,676 +0,0 @@
-%% @author Bob Ippolito <bob at mochimedia.com>
-%% @copyright 2007 Mochi Media, Inc.
-
@@ -2251,8 +1693,22 @@ index 111c37b..0000000
- Acc1 = lists:reverse(xmerl_ucs:to_utf8(C), Acc),
- tokenize_string(B, ?ADV_COL(S, 6), Acc1)
- end;
-- <<_:O/binary, C, _/binary>> ->
-- tokenize_string(B, ?INC_CHAR(S, C), [C | Acc])
+- <<_:O/binary, C1, _/binary>> when C1 < 128 ->
+- tokenize_string(B, ?INC_CHAR(S, C1), [C1 | Acc]);
+- <<_:O/binary, C1, C2, _/binary>> when C1 >= 194, C1 =< 223,
+- C2 >= 128, C2 =< 191 ->
+- tokenize_string(B, ?ADV_COL(S, 2), [C2, C1 | Acc]);
+- <<_:O/binary, C1, C2, C3, _/binary>> when C1 >= 224, C1 =< 239,
+- C2 >= 128, C2 =< 191,
+- C3 >= 128, C3 =< 191 ->
+- tokenize_string(B, ?ADV_COL(S, 3), [C3, C2, C1 | Acc]);
+- <<_:O/binary, C1, C2, C3, C4, _/binary>> when C1 >= 240, C1 =< 244,
+- C2 >= 128, C2 =< 191,
+- C3 >= 128, C3 =< 191,
+- C4 >= 128, C4 =< 191 ->
+- tokenize_string(B, ?ADV_COL(S, 4), [C4, C3, C2, C1 | Acc]);
+- _ ->
+- throw(invalid_utf8)
- end.
-
-tokenize_number(B, S) ->
@@ -2499,7 +1955,9 @@ index 111c37b..0000000
- <<?Q, 16#E0, 16#80,16#7F, ?Q>>,
- <<?Q, 16#F0, 16#80, 16#80, 16#7F, ?Q>>,
- % we don't support code points > 10FFFF per RFC 3629
-- <<?Q, 16#F5, 16#80, 16#80, 16#80, ?Q>>
+- <<?Q, 16#F5, 16#80, 16#80, 16#80, ?Q>>,
+- %% escape characters trigger a different code path
+- <<?Q, $\\, $\n, 16#80, ?Q>>
- ],
- lists:foreach(fun(X) ->
- ok = try decode(X) catch invalid_utf8 -> ok end
@@ -7733,18 +7191,18 @@ index 6835f8f..0000000
-stamp() ->
- erlang:localtime().
diff --git a/test/etap/test_util.erl.in b/test/etap/test_util.erl.in
-index c57d7a8..948958c 100644
+index 1b9e434..2650fbb 100644
--- a/test/etap/test_util.erl.in
+++ b/test/etap/test_util.erl.in
@@ -22,7 +22,7 @@ builddir() ->
"@abs_top_builddir@".
init_code_path() ->
-- Paths = ["couchdb", "ibrowse", "mochiweb"],
-+ Paths = ["couchdb", "ibrowse"],
+- Paths = ["couchdb", "mochiweb"],
++ Paths = ["couchdb"],
lists:foreach(fun(Name) ->
code:add_pathz(filename:join([builddir(), "src", Name]))
end, Paths).
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0007-Workaround-for-system-wide-ibrowse.patch b/couchdb-0009-Fixes-for-system-wide-ibrowse.patch
similarity index 50%
rename from couchdb-0007-Workaround-for-system-wide-ibrowse.patch
rename to couchdb-0009-Fixes-for-system-wide-ibrowse.patch
index d14d671..3007cf7 100644
--- a/couchdb-0007-Workaround-for-system-wide-ibrowse.patch
+++ b/couchdb-0009-Fixes-for-system-wide-ibrowse.patch
@@ -1,16 +1,16 @@
-From d09bcecb010af30c2bc034b15982f72e6ae93c45 Mon Sep 17 00:00:00 2001
+From 8741c02edcd6251a01774471d51325ac7bf055f5 Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
-Date: Tue, 8 Jun 2010 17:30:49 +0400
-Subject: [PATCH 07/13] Workaround for system-wide ibrowse
+Date: Sun, 13 Feb 2011 14:52:57 +0300
+Subject: [PATCH 09/13] Fixes for system-wide ibrowse
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
src/couchdb/couch_rep_changes_feed.erl | 2 +-
- src/couchdb/couch_rep_httpc.erl | 6 +++---
- src/couchdb/couch_rep_reader.erl | 2 +-
- 3 files changed, 5 insertions(+), 5 deletions(-)
+ src/couchdb/couch_rep_httpc.erl | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/couchdb/couch_rep_changes_feed.erl b/src/couchdb/couch_rep_changes_feed.erl
-index 4c7dc35..6669691 100644
+index 4d1afcb..032f62a 100644
--- a/src/couchdb/couch_rep_changes_feed.erl
+++ b/src/couchdb/couch_rep_changes_feed.erl
@@ -20,7 +20,7 @@
@@ -23,7 +23,7 @@ index 4c7dc35..6669691 100644
-record (state, {
changes_from = nil,
diff --git a/src/couchdb/couch_rep_httpc.erl b/src/couchdb/couch_rep_httpc.erl
-index 768d88a..b5a7ed8 100644
+index e535c0d..e13b00c 100644
--- a/src/couchdb/couch_rep_httpc.erl
+++ b/src/couchdb/couch_rep_httpc.erl
@@ -12,7 +12,7 @@
@@ -34,8 +34,8 @@ index 768d88a..b5a7ed8 100644
+-include_lib("ibrowse/include/ibrowse.hrl").
-export([db_exists/1, db_exists/2, full_url/1, request/1, redirected_request/2,
- spawn_worker_process/1, spawn_link_worker_process/1]).
-@@ -199,12 +199,12 @@ redirected_request(Req, RedirectUrl) ->
+ redirect_url/2, spawn_worker_process/1, spawn_link_worker_process/1]).
+@@ -218,7 +218,7 @@ redirected_request(Req, RedirectUrl) ->
spawn_worker_process(Req) ->
Url = ibrowse_lib:parse_url(Req#http_db.url),
@@ -44,25 +44,6 @@ index 768d88a..b5a7ed8 100644
Pid.
spawn_link_worker_process(Req) ->
- Url = ibrowse_lib:parse_url(Req#http_db.url),
-- {ok, Pid} = ibrowse_http_client:start_link(Url),
-+ {ok, Pid} = ibrowse_http_client:start_link({undefined, Url, {[{ssl_imp, new}], (Url#url.protocol == https)}}),
- Pid.
-
- maybe_decompress(Headers, Body) ->
-diff --git a/src/couchdb/couch_rep_reader.erl b/src/couchdb/couch_rep_reader.erl
-index 3edc1f3..8722f3f 100644
---- a/src/couchdb/couch_rep_reader.erl
-+++ b/src/couchdb/couch_rep_reader.erl
-@@ -25,7 +25,7 @@
- -define (MAX_PIPELINE_SIZE, 50).
-
- -include("couch_db.hrl").
---include("../ibrowse/ibrowse.hrl").
-+-include_lib("ibrowse/include/ibrowse.hrl").
-
- -record (state, {
- parent,
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0008-Remove-pid-file-after-stop.patch b/couchdb-0010-Remove-pid-file-after-stop.patch
similarity index 84%
rename from couchdb-0008-Remove-pid-file-after-stop.patch
rename to couchdb-0010-Remove-pid-file-after-stop.patch
index be11df9..b0fb9e6 100644
--- a/couchdb-0008-Remove-pid-file-after-stop.patch
+++ b/couchdb-0010-Remove-pid-file-after-stop.patch
@@ -1,7 +1,7 @@
-From f62be09cd73dcf53703971c1aecb4a3356adc83c Mon Sep 17 00:00:00 2001
+From ca6d9bd34d5231ad285caa5e3ae175cc10d0d36d Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
Date: Mon, 7 Jun 2010 15:08:42 +0400
-Subject: [PATCH 08/13] Remove pid-file after stop
+Subject: [PATCH 10/13] Remove pid-file after stop
---
bin/couchdb.tpl.in | 4 +---
@@ -24,5 +24,5 @@ index 94d4743..af5cb01 100644
if kill -1 $PID 2> /dev/null; then
if test "$1" = "false"; then
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0009-deleting-a-DB-while-it-was-being-opened-would-crash-.patch b/couchdb-0011-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
similarity index 87%
rename from couchdb-0009-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
rename to couchdb-0011-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
index ad0cbcd..4bde1dd 100644
--- a/couchdb-0009-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
+++ b/couchdb-0011-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
@@ -1,7 +1,7 @@
-From bfbe8a8a727f5ddeb80a268ef4915aba27464868 Mon Sep 17 00:00:00 2001
+From 7caf464c8d320ef9da4a019e883c5d50609737ce Mon Sep 17 00:00:00 2001
From: Adam Kocoloski <kocolosk at apache.org>
Date: Sun, 11 Jul 2010 01:00:50 +0000
-Subject: [PATCH 09/13] deleting a DB while it was being opened would crash couch_server
+Subject: [PATCH 11/13] deleting a DB while it was being opened would crash couch_server
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@962964 13f79535-47bb-0310-9956-ffa450edef68
---
@@ -22,5 +22,5 @@ index 43fd904..88bd610 100644
[{_, {opened, Pid, LruTime}}] ->
couch_util:shutdown_sync(Pid),
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0011-Fix-respawn-timeout-to-match-default-value.patch b/couchdb-0012-Change-respawn-timeout-to-0.patch
similarity index 79%
rename from couchdb-0011-Fix-respawn-timeout-to-match-default-value.patch
rename to couchdb-0012-Change-respawn-timeout-to-0.patch
index bf545dc..2ea035d 100644
--- a/couchdb-0011-Fix-respawn-timeout-to-match-default-value.patch
+++ b/couchdb-0012-Change-respawn-timeout-to-0.patch
@@ -1,7 +1,7 @@
-From b112a376b24b831ca7e3160e0e421734982131a9 Mon Sep 17 00:00:00 2001
+From 4184735eefe5be1e756233db17cb77aaa328a740 Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
Date: Thu, 26 Aug 2010 13:22:56 +0400
-Subject: [PATCH 11/13] Fix respawn timeout to match default value
+Subject: [PATCH 12/13] Change respawn timeout to 0.
Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
@@ -20,5 +20,5 @@ index c2a3f2a..f589c0a 100644
+COUCHDB_RESPAWN_TIMEOUT=0
COUCHDB_OPTIONS=
--
-1.7.2.3
+1.7.4
diff --git a/couchdb-0012-Relax-curl-dependency-to-7.15-for-RHEL5.patch b/couchdb-0013-Relax-curl-dependency-to-7.15-for-RHEL5.patch
similarity index 65%
rename from couchdb-0012-Relax-curl-dependency-to-7.15-for-RHEL5.patch
rename to couchdb-0013-Relax-curl-dependency-to-7.15-for-RHEL5.patch
index e2c3406..ab0c105 100644
--- a/couchdb-0012-Relax-curl-dependency-to-7.15-for-RHEL5.patch
+++ b/couchdb-0013-Relax-curl-dependency-to-7.15-for-RHEL5.patch
@@ -1,43 +1,16 @@
-From a3d55325758f58cff0c56574f084fe8cac29c089 Mon Sep 17 00:00:00 2001
+From e95924d09f0c747e454c69dfcfb3a65ccd9fe49f Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
-Date: Sat, 21 Aug 2010 12:49:21 +0400
-Subject: [PATCH 12/13] Relax curl dependency to 7.15 (for RHEL5)
+Date: Sun, 13 Feb 2011 14:59:16 +0300
+Subject: [PATCH 13/13] Relax curl dependency to 7.15 (for RHEL5)
Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
- configure | 8 ++++----
configure.ac | 2 +-
src/couchdb/priv/couch_js/http.c | 14 --------------
- 3 files changed, 5 insertions(+), 19 deletions(-)
+ 2 files changed, 1 insertions(+), 15 deletions(-)
-diff --git a/configure b/configure
-index 3fbc92b..9859f0c 100755
---- a/configure
-+++ b/configure
-@@ -11835,9 +11835,9 @@ fi
- echo "*** Or see http://curl.haxx.se/"
- else
- CURL_VERSION=`$CURL_CONFIG --version | cut -d" " -f2`
-- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl >= 7.18.0" >&5
--$as_echo_n "checking for curl >= 7.18.0... " >&6; }
-- VERSION_CHECK=`expr $CURL_VERSION \>\= 7.18.0`
-+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl >= 7.15.0" >&5
-+$as_echo_n "checking for curl >= 7.15.0... " >&6; }
-+ VERSION_CHECK=`expr $CURL_VERSION \>\= 7.15.0`
- if test "$VERSION_CHECK" = "1" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
- $as_echo "yes" >&6; }
-@@ -11859,7 +11859,7 @@ $as_echo "$CURL_LIBS" >&6; }
- CURL_LIBS=""
- ## If we have a custom action on failure, don't print errors, but
- ## do set a variable so people can do so.
-- echo "can't find curl >= 7.18.0"
-+ echo "can't find curl >= 7.15.0"
- fi
-
-
diff --git a/configure.ac b/configure.ac
-index 905f6d1..0fa689e 100644
+index 9c10cf7..79fa8dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -214,7 +214,7 @@ AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH],
@@ -96,5 +69,5 @@ index 6c2a8a8..a672b66 100644
recv_header(void *ptr, size_t size, size_t nmem, void *data)
{
--
-1.7.2.3
+1.7.4
diff --git a/couchdb.spec b/couchdb.spec
index c92910e..171d5d1 100644
--- a/couchdb.spec
+++ b/couchdb.spec
@@ -3,8 +3,8 @@
%define couchdb_home %{_localstatedir}/lib/couchdb
Name: couchdb
-Version: 1.0.1
-Release: 5%{?dist}
+Version: 1.0.2
+Release: 1%{?dist}
Summary: A document database server, accessible via a RESTful JSON API
Group: Applications/Databases
@@ -12,22 +12,25 @@ License: ASL 2.0
URL: http://couchdb.apache.org/
Source0: http://www.apache.org/dist/%{name}/%{version}/apache-%{name}-%{version}.tar.gz
Source1: %{name}.init
-Patch1: couchdb-0001-Force-init-script-installation.patch
-Patch2: couchdb-0002-Install-into-erllibdir-by-default.patch
-Patch3: couchdb-0003-Remove-bundled-erlang-oauth-library.patch
-Patch4: couchdb-0004-Remove-bundled-erlang-etap-library.patch
-Patch5: couchdb-0005-Remove-bundled-mochiweb-library.patch
-Patch6: couchdb-0006-Remove-bundled-ibrowse-library.patch
-Patch7: couchdb-0007-Workaround-for-system-wide-ibrowse.patch
-Patch8: couchdb-0008-Remove-pid-file-after-stop.patch
-Patch9: couchdb-0009-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
-Patch10: couchdb-0010-Do-not-install-gzipped-docs.patch
-Patch11: couchdb-0011-Fix-respawn-timeout-to-match-default-value.patch
-Patch12: couchdb-0012-Relax-curl-dependency-to-7.15-for-RHEL5.patch
-Patch13: couchdb-0013-No-erlang-min-2-and-erlang-max-2-in-R12B.patch
+Patch1: couchdb-0001-Do-not-gzip-doc-files-and-do-not-install-installatio.patch
+Patch2: couchdb-0002-Install-docs-into-versioned-directory.patch
+Patch3: couchdb-0003-More-directories-to-search-for-place-for-init-script.patch
+Patch4: couchdb-0004-Install-into-erllibdir-by-default.patch
+Patch5: couchdb-0005-Remove-bundled-erlang-oauth-library.patch
+Patch6: couchdb-0006-Remove-bundled-etap-library.patch
+Patch7: couchdb-0007-Remove-bundled-ibrowse-library.patch
+Patch8: couchdb-0008-Remove-bundled-mochiweb-library.patch
+Patch9: couchdb-0009-Fixes-for-system-wide-ibrowse.patch
+Patch10: couchdb-0010-Remove-pid-file-after-stop.patch
+Patch11: couchdb-0011-deleting-a-DB-while-it-was-being-opened-would-crash-.patch
+Patch12: couchdb-0012-Change-respawn-timeout-to-0.patch
+Patch13: couchdb-0013-Relax-curl-dependency-to-7.15-for-RHEL5.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: libtool
BuildRequires: curl-devel
BuildRequires: erlang-erts
BuildRequires: erlang-etap
@@ -42,7 +45,7 @@ BuildRequires: perl(Test::Harness)
Requires: erlang-crypto
Requires: erlang-erts
-Requires: erlang-ibrowse
+Requires: erlang-ibrowse >= 2.1.0
Requires: erlang-inets
Requires: erlang-kernel
Requires: erlang-mochiweb
@@ -70,28 +73,25 @@ JavaScript acting as the default view definition language.
%prep
%setup -q -n apache-%{name}-%{version}
-%patch1 -p1 -b .initenabled
-%patch2 -p1 -b .fix_lib_path
-%patch3 -p1 -b .remove_bundled_oauth
-%patch4 -p1 -b .remove_bundled_etap
-%patch5 -p1 -b .remove_bundled_mochiweb
-%patch6 -p1 -b .remove_bundled_ibrowse
-%patch7 -p1 -b .workaround_for_ssl
-%patch8 -p1 -b .remove_pid_file
-%patch9 -p1 -b .fix_crash
-%patch10 -p1 -b .gzipped_docs
-%patch11 -p1 -b .fix_respawn
+%patch1 -p1 -b .dont_gzip
+%patch2 -p1 -b .use_versioned_docdir
+%patch3 -p1 -b .more_init_dirs
+%patch4 -p1 -b .install_into_erldir
+%patch5 -p1 -b .remove_bundled_oauth
+%patch6 -p1 -b .remove_bundled_etap
+%patch7 -p1 -b .remove_bundled_ibrowse
+%patch8 -p1 -b .remove_bundled_mochiweb
+%patch9 -p1 -b .workaround_for_system_wide_ibrowse
+%patch10 -p1 -b .remove_pid_file
+%patch11 -p1 -b .fix_crash
+%patch12 -p1 -b .fix_respawn
%if 0%{?el5}
# Erlang/OTP R12B5
-%patch12 -p1 -b .curl_7_15
-%patch13 -p1 -b .min_max
+%patch13 -p1 -b .curl_7_15
%endif
-# Restore original timestamps to avoid reconfiguring
-touch -r configure.ac.initenabled configure.ac
-touch -r configure.fix_lib_path configure
-
%build
+autoreconf -ivf
%configure
make %{?_smp_mflags}
@@ -102,8 +102,6 @@ make install DESTDIR=$RPM_BUILD_ROOT
# Install our custom couchdb initscript
install -D -m 755 %{SOURCE1} $RPM_BUILD_ROOT%{_initrddir}/%{name}
-# ...and remove previously installed one
-rm $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/couchdb
# Use /etc/sysconfig instead of /etc/default
mv $RPM_BUILD_ROOT%{_sysconfdir}/{default,sysconfig}
@@ -159,8 +157,9 @@ fi
%changelog
-* Tue Feb 08 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.0.1-5
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+* Thu Nov 25 2010 Peter Lemenkov <lemenkov at gmail.com> 1.0.2-1
+- Ver. 1.0.2
+- Patches were rebased
* Tue Oct 12 2010 Peter Lemenkov <lemenkov at gmail.com> 1.0.1-4
- Added patches for compatibility with R12B5
diff --git a/sources b/sources
index c48a050..9417261 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-001cf286b72492617e9ffba271702a00 apache-couchdb-1.0.1.tar.gz
+7ffbbe0f23f672181c89923c9f7a1de1 apache-couchdb-1.0.2.tar.gz
More information about the scm-commits
mailing list