You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by cm...@apache.org on 2009/02/24 21:56:12 UTC
svn commit: r747541 - in /couchdb/vendor/mochiweb/current: ./ src/ support/
Author: cmlenz
Date: Tue Feb 24 20:56:11 2009
New Revision: 747541
URL: http://svn.apache.org/viewvc?rev=747541&view=rev
Log:
Updated MochiWeb vendor branch to r96 from <http://mochiweb.googlecode.com/svn/trunk/>.
Modified:
couchdb/vendor/mochiweb/current/Makefile
couchdb/vendor/mochiweb/current/src/Makefile
couchdb/vendor/mochiweb/current/src/mochijson.erl
couchdb/vendor/mochiweb/current/src/mochijson2.erl
couchdb/vendor/mochiweb/current/src/mochiweb.app
couchdb/vendor/mochiweb/current/src/mochiweb_headers.erl
couchdb/vendor/mochiweb/current/src/mochiweb_html.erl
couchdb/vendor/mochiweb/current/src/mochiweb_http.erl
couchdb/vendor/mochiweb/current/src/mochiweb_request.erl
couchdb/vendor/mochiweb/current/src/mochiweb_response.erl
couchdb/vendor/mochiweb/current/src/mochiweb_util.erl
couchdb/vendor/mochiweb/current/support/include.mk
Modified: couchdb/vendor/mochiweb/current/Makefile
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/Makefile?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/Makefile (original)
+++ couchdb/vendor/mochiweb/current/Makefile Tue Feb 24 20:56:11 2009
@@ -1,5 +1,8 @@
all:
- (cd src;$(MAKE))
+ (cd src;$(MAKE) all)
+
+edoc:
+ (cd src;$(MAKE) edoc)
test:
(cd src;$(MAKE) test)
Modified: couchdb/vendor/mochiweb/current/src/Makefile
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/Makefile?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/Makefile (original)
+++ couchdb/vendor/mochiweb/current/src/Makefile Tue Feb 24 20:56:11 2009
@@ -1,5 +1,8 @@
include ../support/include.mk
+APPLICATION=mochiweb
+DOC_OPTS={dir,\"../doc\"}
+
all: $(EBIN_FILES)
debug:
@@ -8,5 +11,10 @@
clean:
rm -rf $(EBIN_FILES)
+edoc:
+ $(ERL) -noshell -pa ../ebin \
+ -eval "edoc:application($(APPLICATION), \".\", [$(DOC_OPTS)])" \
+ -s init stop
+
test: all
- $(ERL) -noshell -pa ../ebin -s mochiweb test -s init stop
+ $(ERL) -noshell -pa ../ebin -s $(APPLICATION) test -s init stop
Modified: couchdb/vendor/mochiweb/current/src/mochijson.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochijson.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochijson.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochijson.erl Tue Feb 24 20:56:11 2009
@@ -478,10 +478,6 @@
true = equiv(E, decode(encode(E))),
test_one(Rest, 1+N).
-e2j_test_vec(unicode) ->
- [
- {"foo" ++ [500] ++ "bar", [$", $f, $o, $o, 500, $b, $a, $r, $"]}
- ];
e2j_test_vec(utf8) ->
[
{1, "1"},
Modified: couchdb/vendor/mochiweb/current/src/mochijson2.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochijson2.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochijson2.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochijson2.erl Tue Feb 24 20:56:11 2009
@@ -132,13 +132,81 @@
lists:reverse([$\} | Acc1]).
json_encode_string(A, _State) when is_atom(A) ->
- json_encode_string_unicode(xmerl_ucs:from_utf8(atom_to_list(A)), [?Q]);
+ L = atom_to_list(A),
+ case json_string_is_safe(L) of
+ true ->
+ [?Q, L, ?Q];
+ false ->
+ json_encode_string_unicode(xmerl_ucs:from_utf8(L), [?Q])
+ end;
json_encode_string(B, _State) when is_binary(B) ->
- json_encode_string_unicode(xmerl_ucs:from_utf8(B), [?Q]);
+ case json_bin_is_safe(B) of
+ true ->
+ [?Q, B, ?Q];
+ false ->
+ json_encode_string_unicode(xmerl_ucs:from_utf8(B), [?Q])
+ end;
json_encode_string(I, _State) when is_integer(I) ->
- json_encode_string_unicode(integer_to_list(I), [?Q]);
+ [?Q, integer_to_list(I), ?Q];
json_encode_string(L, _State) when is_list(L) ->
- json_encode_string_unicode(L, [?Q]).
+ case json_string_is_safe(L) of
+ true ->
+ [?Q, L, ?Q];
+ false ->
+ json_encode_string_unicode(L, [?Q])
+ end.
+
+json_string_is_safe([]) ->
+ true;
+json_string_is_safe([C | Rest]) ->
+ case C of
+ ?Q ->
+ false;
+ $\\ ->
+ false;
+ $\b ->
+ false;
+ $\f ->
+ false;
+ $\n ->
+ false;
+ $\r ->
+ false;
+ $\t ->
+ false;
+ C when C >= 0, C < $\s; C >= 16#7f, C =< 16#10FFFF ->
+ false;
+ C when C < 16#7f ->
+ json_string_is_safe(Rest);
+ _ ->
+ false
+ end.
+
+json_bin_is_safe(<<>>) ->
+ true;
+json_bin_is_safe(<<C, Rest/binary>>) ->
+ case C of
+ ?Q ->
+ false;
+ $\\ ->
+ false;
+ $\b ->
+ false;
+ $\f ->
+ false;
+ $\n ->
+ false;
+ $\r ->
+ false;
+ $\t ->
+ false;
+ C when C >= 0, C < $\s; C >= 16#7f, C =< 16#10FFFF ->
+ false;
+ C when C < 16#7f ->
+ json_bin_is_safe(Rest);
+ _ ->
+ false
+ end.
json_encode_string_unicode([], Acc) ->
lists:reverse([$\" | Acc]);
@@ -260,8 +328,28 @@
decode_array(B, S1#decoder{state=any}, Acc)
end.
-tokenize_string(B, S) ->
- tokenize_string(B, S, []).
+tokenize_string(B, S=#decoder{offset=O}) ->
+ case tokenize_string_fast(B, O) of
+ {escape, O1} ->
+ Length = O1 - O,
+ S1 = ?ADV_COL(S, Length),
+ <<_:O/binary, Head:Length/binary, _/binary>> = B,
+ tokenize_string(B, S1, lists:reverse(binary_to_list(Head)));
+ O1 ->
+ Length = O1 - O,
+ <<_:O/binary, String:Length/binary, ?Q, _/binary>> = B,
+ {{const, String}, ?ADV_COL(S, Length + 1)}
+ end.
+
+tokenize_string_fast(B, O) ->
+ case B of
+ <<_:O/binary, ?Q, _/binary>> ->
+ O;
+ <<_:O/binary, C, _/binary>> when C =/= $\\ ->
+ tokenize_string_fast(B, 1 + O);
+ _ ->
+ {escape, O}
+ end.
tokenize_string(B, S=#decoder{offset=O}, Acc) ->
case B of
Modified: couchdb/vendor/mochiweb/current/src/mochiweb.app
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb.app?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb.app (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb.app Tue Feb 24 20:56:11 2009
@@ -21,7 +21,10 @@
mochiweb_socket_server,
mochiweb_sup,
mochiweb_util,
- reloader
+ reloader,
+ mochifmt,
+ mochifmt_std,
+ mochifmt_records
]},
{registered, []},
{mod, {mochiweb_app, []}},
Modified: couchdb/vendor/mochiweb/current/src/mochiweb_headers.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb_headers.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb_headers.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb_headers.erl Tue Feb 24 20:56:11 2009
@@ -6,7 +6,7 @@
-module(mochiweb_headers).
-author('bob@mochimedia.com').
-export([empty/0, from_list/1, insert/3, enter/3, get_value/2, lookup/2]).
--export([get_primary_value/2]).
+-export([delete_any/2, get_primary_value/2]).
-export([default/3, enter_from_list/2, default_from_list/2]).
-export([to_list/1, make/1]).
-export([test/0]).
@@ -35,6 +35,8 @@
H3),
"application/x-www-form-urlencoded" = ?MODULE:get_primary_value(
"content-type", H4),
+ H4 = ?MODULE:delete_any("nonexistent-header", H4),
+ H3 = ?MODULE:delete_any("content-type", H4),
ok.
%% @spec empty() -> headers()
@@ -145,6 +147,12 @@
gb_trees:update(K1, {K0, V2}, T)
end.
+%% @spec delete_any(key(), headers()) -> headers()
+%% @doc Delete the header corresponding to key if it is present.
+delete_any(K, T) ->
+ K1 = normalize(K),
+ gb_trees:delete_any(K1, T).
+
%% Internal API
expand({array, L}) ->
Modified: couchdb/vendor/mochiweb/current/src/mochiweb_html.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb_html.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb_html.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb_html.erl Tue Feb 24 20:56:11 2009
@@ -129,7 +129,9 @@
test() ->
test_destack(),
test_tokens(),
+ test_tokens2(),
test_parse(),
+ test_parse2(),
test_parse_tokens(),
test_escape(),
test_escape_attr(),
@@ -426,6 +428,34 @@
Expect = parse(D0),
ok.
+test_tokens2() ->
+ D0 = <<"<channel><title>from __future__ import *</title><link>http://bob.pythonmac.org</link><description>Bob's Rants</description></channel>">>,
+ Expect = [{start_tag,<<"channel">>,[],false},
+ {start_tag,<<"title">>,[],false},
+ {data,<<"from __future__ import *">>,false},
+ {end_tag,<<"title">>},
+ {start_tag,<<"link">>,[],true},
+ {data,<<"http://bob.pythonmac.org">>,false},
+ {end_tag,<<"link">>},
+ {start_tag,<<"description">>,[],false},
+ {data,<<"Bob's Rants">>,false},
+ {end_tag,<<"description">>},
+ {end_tag,<<"channel">>}],
+ Expect = tokens(D0),
+ ok.
+
+test_parse2() ->
+ D0 = <<"<channel><title>from __future__ import *</title><link>http://bob.pythonmac.org<br>foo</link><description>Bob's Rants</description></channel>">>,
+ Expect = {<<"channel">>,[],
+ [{<<"title">>,[],[<<"from __future__ import *">>]},
+ {<<"link">>,[],[
+ <<"http://bob.pythonmac.org">>,
+ {<<"br">>,[],[]},
+ <<"foo">>]},
+ {<<"description">>,[],[<<"Bob's Rants">>]}]},
+ Expect = parse(D0),
+ ok.
+
test_parse_tokens() ->
D0 = [{doctype,[<<"HTML">>,<<"PUBLIC">>,<<"-//W3C//DTD HTML 4.01 Transitional//EN">>]},
{data,<<"\n">>,true},
@@ -562,8 +592,23 @@
end,
case lists:splitwith(F, Stack) of
{_, []} ->
- %% No match, no state change
- Stack;
+ %% If we're parsing something like XML we might find
+ %% a <link>tag</link> that is normally a singleton
+ %% in HTML but isn't here
+ case {is_singleton(TagName), Stack} of
+ {true, [{T0, A0, Acc0} | Post0]} ->
+ case lists:splitwith(F, Acc0) of
+ {_, []} ->
+ %% Actually was a singleton
+ Stack;
+ {Pre, [{T1, A1, []} | Post1]} ->
+ [{T0, A0, [{T1, A1, lists:reverse(Pre)} | Post1]}
+ | Post0]
+ end;
+ _ ->
+ %% No match, no state change
+ Stack
+ end;
{_Pre, [_T]} ->
%% Unfurl the whole stack, we're done
destack(Stack);
Modified: couchdb/vendor/mochiweb/current/src/mochiweb_http.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb_http.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb_http.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb_http.erl Tue Feb 24 20:56:11 2009
@@ -10,6 +10,7 @@
-define(IDLE_TIMEOUT, 30000).
+-define(MAX_HEADERS, 1000).
-define(DEFAULTS, [{name, ?MODULE},
{port, 8888}]).
@@ -37,7 +38,7 @@
stop(Name) ->
mochiweb_socket_server:stop(Name).
-
+
start() ->
start([{ip, "127.0.0.1"},
{loop, {?MODULE, default_body}}]).
@@ -80,12 +81,12 @@
{body, Req:recv_body()},
Req:dump()]]),
Req:ok({"text/html", [], frm(Body)});
-default_body(Req, 'POST', _Path) ->
+default_body(Req, 'POST', _Path) ->
Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()},
{parse_cookie, Req:parse_cookie()},
{parse_post, Req:parse_post()},
Req:dump()]]),
- Req:ok({"text/html", [], frm(Body)});
+ Req:ok({"text/html", [], frm(Body)});
default_body(Req, _Method, _Path) ->
Req:respond({501, [], []}).
@@ -99,7 +100,7 @@
request(Socket, Body) ->
case gen_tcp:recv(Socket, 0, ?IDLE_TIMEOUT) of
{ok, {http_request, Method, Path, Version}} ->
- headers(Socket, {Method, Path, Version}, [], Body);
+ headers(Socket, {Method, Path, Version}, [], Body, 0);
{error, {http_error, "\r\n"}} ->
request(Socket, Body);
{error, {http_error, "\n"}} ->
@@ -109,7 +110,15 @@
exit(normal)
end.
-headers(Socket, Request, Headers, Body) ->
+headers(Socket, Request, Headers, _Body, ?MAX_HEADERS) ->
+ %% Too many headers sent, bad request.
+ inet:setopts(Socket, [{packet, raw}]),
+ Req = mochiweb:new_request({Socket, Request,
+ lists:reverse(Headers)}),
+ Req:respond({400, [], []}),
+ gen_tcp:close(Socket),
+ exit(normal);
+headers(Socket, Request, Headers, Body, HeaderCount) ->
case gen_tcp:recv(Socket, 0, ?IDLE_TIMEOUT) of
{ok, http_eoh} ->
inet:setopts(Socket, [{packet, raw}]),
@@ -125,7 +134,8 @@
?MODULE:loop(Socket, Body)
end;
{ok, {http_header, _, Name, _, Value}} ->
- headers(Socket, Request, [{Name, Value} | Headers], Body);
+ headers(Socket, Request, [{Name, Value} | Headers], Body,
+ 1 + HeaderCount);
_Other ->
gen_tcp:close(Socket),
exit(normal)
Modified: couchdb/vendor/mochiweb/current/src/mochiweb_request.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb_request.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb_request.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb_request.erl Tue Feb 24 20:56:11 2009
@@ -12,7 +12,7 @@
-define(READ_SIZE, 8192).
-export([get_header_value/1, get_primary_header_value/1, get/1, dump/0]).
--export([send/1, recv/1, recv/2, recv_body/0, recv_body/1]).
+-export([send/1, recv/1, recv/2, recv_body/0, recv_body/1, stream_body/3]).
-export([start_response/1, start_response_length/1, start_raw_response/1]).
-export([respond/1, ok/1]).
-export([not_found/0, not_found/1]).
@@ -171,28 +171,54 @@
%% @doc Receive the body of the HTTP request (defined by Content-Length).
%% Will receive up to MaxBody bytes.
recv_body(MaxBody) ->
+ % we could use a sane constant for max chunk size
+ Body = stream_body(?MAX_RECV_BODY, fun
+ ({0, _ChunkedFooter}, {_LengthAcc, BinAcc}) ->
+ iolist_to_binary(lists:reverse(BinAcc));
+ ({Length, Bin}, {LengthAcc, BinAcc}) ->
+ NewLength = Length + LengthAcc,
+ if NewLength > MaxBody ->
+ exit({body_too_large, chunked});
+ true ->
+ {NewLength, [Bin | BinAcc]}
+ end
+ end, {0, []}, MaxBody),
+ put(?SAVE_BODY, Body),
+ Body.
+
+stream_body(MaxChunkSize, ChunkFun, FunState) ->
+ stream_body(MaxChunkSize, ChunkFun, FunState, undefined).
+
+stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength) ->
+
case get_header_value("expect") of
"100-continue" ->
start_raw_response({100, gb_trees:empty()});
_Else ->
ok
end,
- Body = case body_length() of
- undefined ->
- undefined;
- {unknown_transfer_encoding, Unknown} ->
- exit({unknown_transfer_encoding, Unknown});
- chunked ->
- read_chunked_body(MaxBody, []);
- 0 ->
- <<>>;
- Length when is_integer(Length), Length =< MaxBody ->
- recv(Length);
- Length ->
- exit({body_too_large, Length})
- end,
- put(?SAVE_BODY, Body),
- Body.
+ case body_length() of
+ undefined ->
+ undefined;
+ {unknown_transfer_encoding, Unknown} ->
+ exit({unknown_transfer_encoding, Unknown});
+ chunked ->
+ % In this case the MaxBody is actually used to
+ % determine the maximum allowed size of a single
+ % chunk.
+ stream_chunked_body(MaxChunkSize, ChunkFun, FunState);
+ 0 ->
+ <<>>;
+ Length when is_integer(Length) ->
+ case MaxBodyLength of
+ MaxBodyLength when is_integer(MaxBodyLength), MaxBodyLength < Length ->
+ exit({body_too_large, content_length});
+ _ ->
+ stream_unchunked_body(Length, MaxChunkSize, ChunkFun, FunState)
+ end;
+ Length ->
+ exit({length_not_integer, Length})
+ end.
%% @spec start_response({integer(), ioheaders()}) -> response()
@@ -220,12 +246,18 @@
%% @spec start_response_length({integer(), ioheaders(), integer()}) -> response()
%% @doc Start the HTTP response by sending the Code HTTP response and
-%% ResponseHeaders including a Content-Length of Length. The server
-%% will set header defaults such as Server
+%% ResponseHeaders including a Content-Length of Length if appropriate.
+%% The server will set header defaults such as Server
%% and Date if not present in ResponseHeaders.
start_response_length({Code, ResponseHeaders, Length}) ->
HResponse = mochiweb_headers:make(ResponseHeaders),
- HResponse1 = mochiweb_headers:enter("Content-Length", Length, HResponse),
+ HResponse1 = case (Length =/= 0 orelse (Code >= 200 andalso Code < 300)) of
+ true ->
+ mochiweb_headers:enter("Content-Length", Length,
+ HResponse);
+ false ->
+ HResponse
+ end,
start_response({Code, HResponse1}).
%% @spec respond({integer(), ioheaders(), iodata() | chunked | {file, IoDevice}}) -> response()
@@ -408,17 +440,33 @@
Cached
end.
-read_chunked_body(Max, Acc) ->
+%% @spec stream_chunked_body(integer(), fun(), term()) -> term()
+%% @doc The function is called for each chunk.
+%% Used internally by read_chunked_body.
+stream_chunked_body(MaxChunkSize, Fun, FunState) ->
case read_chunk_length() of
0 ->
- read_chunk(0),
- iolist_to_binary(lists:reverse(Acc));
- Length when Length > Max ->
- exit({body_too_large, chunked});
+ Fun({0, read_chunk(0)}, FunState);
+ Length when Length > MaxChunkSize ->
+ NewState = read_sub_chunks(Length, MaxChunkSize, Fun, FunState),
+ stream_chunked_body(MaxChunkSize, Fun, NewState);
Length ->
- read_chunked_body(Max - Length, [read_chunk(Length) | Acc])
+ NewState = Fun({Length, read_chunk(Length)}, FunState),
+ stream_chunked_body(MaxChunkSize, Fun, NewState)
end.
+stream_unchunked_body(0, _MaxChunkSize, Fun, FunState) ->
+ Fun({0, <<>>}, FunState);
+stream_unchunked_body(Length, MaxChunkSize, Fun, FunState) when Length > MaxChunkSize ->
+ Bin = recv(MaxChunkSize),
+ NewState = Fun({MaxChunkSize, Bin}, FunState),
+ stream_unchunked_body(Length - MaxChunkSize, MaxChunkSize, Fun, NewState);
+stream_unchunked_body(Length, MaxChunkSize, Fun, FunState) ->
+ Bin = recv(Length),
+ NewState = Fun({Length, Bin}, FunState),
+ stream_unchunked_body(0, MaxChunkSize, Fun, NewState).
+
+
%% @spec read_chunk_length() -> integer()
%% @doc Read the length of the next HTTP chunk.
read_chunk_length() ->
@@ -461,6 +509,14 @@
exit(normal)
end.
+read_sub_chunks(Length, MaxChunkSize, Fun, FunState) when Length > MaxChunkSize ->
+ Bin = recv(MaxChunkSize),
+ NewState = Fun({size(Bin), Bin}, FunState),
+ read_sub_chunks(Length - MaxChunkSize, MaxChunkSize, Fun, NewState);
+
+read_sub_chunks(Length, _MaxChunkSize, Fun, FunState) ->
+ Fun({Length, read_chunk(Length)}, FunState).
+
%% @spec serve_file(Path, DocRoot) -> Response
%% @doc Serve a file relative to DocRoot.
serve_file(Path, DocRoot) ->
Modified: couchdb/vendor/mochiweb/current/src/mochiweb_response.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb_response.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb_response.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb_response.erl Tue Feb 24 20:56:11 2009
@@ -50,8 +50,7 @@
case Request:get(version) of
Version when Version >= {1, 1} ->
Length = iolist_size(Data),
- send(io_lib:format("~.16b\r\n", [Length])),
- send([Data, <<"\r\n">>]);
+ send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>]);
_ ->
send(Data)
end.
Modified: couchdb/vendor/mochiweb/current/src/mochiweb_util.erl
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/src/mochiweb_util.erl?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/src/mochiweb_util.erl (original)
+++ couchdb/vendor/mochiweb/current/src/mochiweb_util.erl Tue Feb 24 20:56:11 2009
@@ -133,12 +133,16 @@
revjoin([S | Rest], Separator, Acc) ->
revjoin(Rest, Separator, [S, Separator | Acc]).
-%% @spec quote_plus(atom() | integer() | string()) -> string()
+%% @spec quote_plus(atom() | integer() | float() | string() | binary()) -> string()
%% @doc URL safe encoding of the given term.
quote_plus(Atom) when is_atom(Atom) ->
quote_plus(atom_to_list(Atom));
quote_plus(Int) when is_integer(Int) ->
quote_plus(integer_to_list(Int));
+quote_plus(Binary) when is_binary(Binary) ->
+ quote_plus(binary_to_list(Binary));
+quote_plus(Float) when is_float(Float) ->
+ quote_plus(mochinum:digits(Float));
quote_plus(String) ->
quote_plus(String, []).
@@ -527,6 +531,7 @@
test_quote_plus() ->
"foo" = quote_plus(foo),
"1" = quote_plus(1),
+ "1.1" = quote_plus(1.1),
"foo" = quote_plus("foo"),
"foo+bar" = quote_plus("foo bar"),
"foo%0A" = quote_plus("foo\n"),
Modified: couchdb/vendor/mochiweb/current/support/include.mk
URL: http://svn.apache.org/viewvc/couchdb/vendor/mochiweb/current/support/include.mk?rev=747541&r1=747540&r2=747541&view=diff
==============================================================================
--- couchdb/vendor/mochiweb/current/support/include.mk (original)
+++ couchdb/vendor/mochiweb/current/support/include.mk Tue Feb 24 20:56:11 2009
@@ -19,17 +19,14 @@
endif
EBIN_DIR := ../ebin
-DOC_DIR := ../doc
EMULATOR := beam
ERL_SOURCES := $(wildcard *.erl)
ERL_HEADERS := $(wildcard *.hrl) $(wildcard ../include/*.hrl)
ERL_OBJECTS := $(ERL_SOURCES:%.erl=$(EBIN_DIR)/%.$(EMULATOR))
-ERL_DOCUMENTS := $(ERL_SOURCES:%.erl=$(DOC_DIR)/%.html)
ERL_OBJECTS_LOCAL := $(ERL_SOURCES:%.erl=./%.$(EMULATOR))
APP_FILES := $(wildcard *.app)
-EBIN_FILES = $(ERL_OBJECTS) $(ERL_DOCUMENTS) $(APP_FILES:%.app=../ebin/%.app)
-EBIN_FILES_NO_DOCS = $(ERL_OBJECTS) $(APP_FILES:%.app=../ebin/%.app)
+EBIN_FILES = $(ERL_OBJECTS) $(APP_FILES:%.app=../ebin/%.app)
MODULES = $(ERL_SOURCES:%.erl=%)
../ebin/%.app: %.app
@@ -40,7 +37,3 @@
./%.$(EMULATOR): %.erl
$(ERLC) $(ERLC_FLAGS) -o . $<
-
-$(DOC_DIR)/%.html: %.erl
- $(ERL) -noshell -run edoc file $< -run init stop
- mv *.html $(DOC_DIR)