summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Cottlehuber <dch@apache.org>2014-03-21 16:38:57 +0100
committerDave Cottlehuber <dch@apache.org>2014-03-21 16:38:57 +0100
commit38980586cdb5df365f9de47f3b2d1d281e767bd5 (patch)
tree328d51e725bc4d4119ebd4842a4ddbbd263a520d
parentb63f393b8fad85bd4fca022a86227e4540c48a6b (diff)
downloadcouchdb-2041-update-ibrowse.tar.gz
ibrowse: include fix from refuge/benoitc in d1a5bb02041-update-ibrowse
-rw-r--r--src/ibrowse/Makefile.am2
-rw-r--r--src/ibrowse/ibrowse.app.in2
-rw-r--r--src/ibrowse/ibrowse.erl2
-rw-r--r--src/ibrowse/ibrowse_http_client.erl42
4 files changed, 37 insertions, 11 deletions
diff --git a/src/ibrowse/Makefile.am b/src/ibrowse/Makefile.am
index 7c48169b1..e3dd5cc78 100644
--- a/src/ibrowse/Makefile.am
+++ b/src/ibrowse/Makefile.am
@@ -10,7 +10,7 @@
## License for the specific language governing permissions and limitations under
## the License.
-ibrowseebindir = $(localerlanglibdir)/ibrowse-2.2.0/ebin
+ibrowseebindir = $(localerlanglibdir)/ibrowse-4.1.0/ebin
ibrowse_file_collection = \
ibrowse.app.in \
diff --git a/src/ibrowse/ibrowse.app.in b/src/ibrowse/ibrowse.app.in
index f318aef0f..16e3552c0 100644
--- a/src/ibrowse/ibrowse.app.in
+++ b/src/ibrowse/ibrowse.app.in
@@ -1,6 +1,6 @@
{application, ibrowse,
[{description, "Erlang HTTP client application"},
- {vsn, "4.1.0"},
+ {vsn, "4.1.0-d1a5bb0"},
{registered, [ibrowse_sup, ibrowse]},
{applications, [kernel,stdlib]},
{env, []},
diff --git a/src/ibrowse/ibrowse.erl b/src/ibrowse/ibrowse.erl
index fc90dc6bc..85bb75cb0 100644
--- a/src/ibrowse/ibrowse.erl
+++ b/src/ibrowse/ibrowse.erl
@@ -150,7 +150,7 @@ stop() ->
%% The Status return value indicates the HTTP status code returned by the webserver
%% @spec send_req(Url::string(), Headers::headerList(), Method::method()) -> response()
%% headerList() = [{header(), value()}]
-%% header() = atom() | string()
+%% header() = atom() | string() | binary()
%% value() = term()
%% method() = get | post | head | options | put | delete | trace | mkcol | propfind | proppatch | lock | unlock | move | copy
%% Status = string()
diff --git a/src/ibrowse/ibrowse_http_client.erl b/src/ibrowse/ibrowse_http_client.erl
index 64fc443a7..0cc287b9d 100644
--- a/src/ibrowse/ibrowse_http_client.erl
+++ b/src/ibrowse/ibrowse_http_client.erl
@@ -587,7 +587,11 @@ do_send_body(Body, State, _TE) ->
generate_body({Source, Source_state} = In) when is_function(Source) ->
case Source(Source_state) of
{ok, Data, Source_state_1} ->
- {{ok, Data}, {Source, Source_state_1}};
+ {{ok, Data, Source_state_1}, Source};
+ {eof, Source_state_1} ->
+ {{eof, Source_state_1}, Source};
+ eof ->
+ {eof, Source};
Ret ->
{Ret, In}
end;
@@ -618,6 +622,16 @@ do_send_body_1({Resp, Source}, State, TE, Acc) when is_function(Source) ->
[Data | Acc]
end,
do_send_body_1(generate_body({Source, New_source_state}), State, TE, Acc_1);
+ {eof, _New_source_state} ->
+ case TE of
+ true ->
+ ok = do_send(<<"0\r\n\r\n">>, State),
+ {ok, []};
+ _ ->
+ Body = list_to_binary(lists:reverse(Acc)),
+ ok = do_send(Body, State),
+ {ok, Body}
+ end;
eof when TE == true ->
ok = do_send(<<"0\r\n\r\n">>, State),
{ok, []};
@@ -924,7 +938,7 @@ make_request(Method, Headers, AbsPath, RelPath, Body, Options,
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) ->
+ ({X, Y}) when is_list(X); is_binary(X) ->
{to_lower(X), X, Y}
end,
Headers_0 = [Fun1(X) || X <- Headers],
@@ -1010,7 +1024,7 @@ encode_headers(L) ->
encode_headers(L, []).
encode_headers([{http_vsn, _Val} | T], Acc) ->
encode_headers(T, Acc);
-encode_headers([{Name,Val} | T], Acc) when is_list(Name) ->
+encode_headers([{Name,Val} | T], Acc) when is_list(Name); is_binary(Name) ->
encode_headers(T, [[Name, ": ", fmt_val(Val), crnl()] | Acc]);
encode_headers([{Name,Val} | T], Acc) when is_atom(Name) ->
encode_headers(T, [[atom_to_list(Name), ": ", fmt_val(Val), crnl()] | Acc]);
@@ -1072,7 +1086,7 @@ parse_response(Data, #state{reply_buffer = Acc, reqs = Reqs,
{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")),
+ ConnClose = to_lower(get_header_value("connection", LCHeaders, "false")),
IsClosing = is_connection_closing(HttpVsn, ConnClose),
State_0 = case IsClosing of
true ->
@@ -1096,11 +1110,11 @@ parse_response(Data, #state{reply_buffer = Acc, reqs = Reqs,
http_status_code=StatCode}
end,
put(conn_close, ConnClose),
- TransferEncodings = to_lower(get_value("transfer-encoding", LCHeaders, "false")),
+ TransferEncodings = to_lower(get_header_value("transfer-encoding", LCHeaders, "false")),
IsChunked = lists:any(fun(Enc) -> string:strip(Enc) =:= "chunked" end,
string:tokens(TransferEncodings, ",")),
Head_response_with_body = lists:member({workaround, head_response_with_body}, Options),
- case get_value("content-length", LCHeaders, undefined) of
+ case get_header_value("content-length", LCHeaders, undefined) of
_ when Method == connect,
hd(StatCode) == $2 ->
{_, Reqs_1} = queue:out(Reqs),
@@ -1181,12 +1195,12 @@ parse_response(Data, #state{reply_buffer = Acc, reqs = Reqs,
%% Some servers send 303 requests without a body.
%% RFC2616 says that they SHOULD, but they dont.
case ibrowse:get_config_value(allow_303_with_no_body, false) of
- false ->
+ false ->
fail_pipelined_requests(State_1,
{error, {content_length_undefined,
{stat_code, StatCode}, Headers}}),
{error, content_length_undefined};
- true ->
+ true ->
{_, 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,
@@ -1906,6 +1920,8 @@ cancel_timer(Ref, {eat_message, Msg}) ->
make_req_id() ->
now().
+to_lower(Str) when is_binary(Str) ->
+ to_lower(binary_to_list(Str));
to_lower(Str) ->
to_lower(Str, []).
to_lower([H|T], Acc) when H >= $A, H =< $Z ->
@@ -2021,3 +2037,13 @@ to_binary({X, _}) when is_function(X) -> to_binary(X);
to_binary(X) when is_function(X) -> <<"body generated by function">>;
to_binary(X) when is_list(X) -> list_to_binary(X);
to_binary(X) when is_binary(X) -> X.
+
+get_header_value(Name, Headers, Default_val) ->
+ case lists:keysearch(Name, 1, Headers) of
+ false ->
+ Default_val;
+ {value, {_, Val}} when is_binary(Val) ->
+ binary_to_list(Val);
+ {value, {_, Val}} ->
+ Val
+ end.