You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2008/07/04 20:44:45 UTC
svn commit: r674105 - in /incubator/couchdb/branches/runtimeconfig: ./ bin/
share/server/ src/couchdb/ src/mochiweb/
Author: jan
Date: Fri Jul 4 11:44:44 2008
New Revision: 674105
URL: http://svn.apache.org/viewvc?rev=674105&view=rev
Log:
Merged revisions 670653,670720,670732,670737-670738,670774,671125,671151,671610,673631,673634,673778 via svnmerge from
https://svn.apache.org/repos/asf/incubator/couchdb/trunk
Modified:
incubator/couchdb/branches/runtimeconfig/ (props changed)
incubator/couchdb/branches/runtimeconfig/NEWS
incubator/couchdb/branches/runtimeconfig/acinclude.m4.in
incubator/couchdb/branches/runtimeconfig/bin/couchdb.tpl.in
incubator/couchdb/branches/runtimeconfig/share/server/main.js
incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_httpd.erl
incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_util.erl
incubator/couchdb/branches/runtimeconfig/src/mochiweb/Makefile.am
incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_html.erl
incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_request.erl
incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_socket_server.erl
Propchange: incubator/couchdb/branches/runtimeconfig/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Jul 4 11:44:44 2008
@@ -1 +1 @@
-/incubator/couchdb/trunk:1-669515
+/incubator/couchdb/trunk:1-674103
Modified: incubator/couchdb/branches/runtimeconfig/NEWS
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/NEWS?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/NEWS (original)
+++ incubator/couchdb/branches/runtimeconfig/NEWS Fri Jul 4 11:44:44 2008
@@ -5,6 +5,11 @@
http://wiki.apache.org/couchdb/BreakingChanges
+Version 0.9.0-incubating
+------------------------
+
+This release is still under development.
+
Version 0.8.0-incubating
------------------------
@@ -18,7 +23,7 @@
* Miscellaneous improvements to system integration and portability.
* Swapped out Erlang's inets HTTP server for the Mochiweb HTTP server.
* SpiderMonkey is no longer included with CouchDB, but rather treated as an
- external dependendancy.
+ external dependency.
* Added bits of awesome.
Please note that there have been many backwards incomatible changes in this
Modified: incubator/couchdb/branches/runtimeconfig/acinclude.m4.in
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/acinclude.m4.in?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/acinclude.m4.in (original)
+++ incubator/couchdb/branches/runtimeconfig/acinclude.m4.in Fri Jul 4 11:44:44 2008
@@ -17,9 +17,9 @@
m4_define([LOCAL_PACKAGE_NAME], [Apache CouchDB])
m4_define([LOCAL_VERSION_MAJOR], [0])
-m4_define([LOCAL_VERSION_MINOR], [8])
+m4_define([LOCAL_VERSION_MINOR], [9])
m4_define([LOCAL_VERSION_REVISION], [0])
-m4_define([LOCAL_VERSION_STAGE], [])
+m4_define([LOCAL_VERSION_STAGE], [a])
m4_define([LOCAL_VERSION_RELEASE], [%release%])
m4_define([LOCAL_VERSION_STATUS], [incubating])
m4_define([LOCAL_VERSION_PRIMARY],
Modified: incubator/couchdb/branches/runtimeconfig/bin/couchdb.tpl.in
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/bin/couchdb.tpl.in?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/bin/couchdb.tpl.in (original)
+++ incubator/couchdb/branches/runtimeconfig/bin/couchdb.tpl.in Fri Jul 4 11:44:44 2008
@@ -186,7 +186,7 @@
command="`%ICU_CONFIG% --invoke` \
%ERL% $interactive_option -smp auto -sasl errlog_type error \
-pa %localerlanglibdir%/couch-%version%/ebin \
- %localerlanglibdir%/mochiweb-r76/ebin \
+ %localerlanglibdir%/mochiweb-r82/ebin \
-eval \"application:load(inets)\" \
-eval \"application:load(crypto)\" \
-eval \"application:load(couch)\" \
Modified: incubator/couchdb/branches/runtimeconfig/share/server/main.js
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/share/server/main.js?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/share/server/main.js [utf-8] (original)
+++ incubator/couchdb/branches/runtimeconfig/share/server/main.js [utf-8] Fri Jul 4 11:44:44 2008
@@ -74,15 +74,13 @@
// ]
//
var doc = cmd[1];
- seal(doc); // seal to prevent map functions from changing doc
+ recursivelySeal(doc); // seal to prevent map functions from changing doc
var buf = [];
for (var i = 0; i < funs.length; i++) {
map_results = [];
try {
funs[i](doc);
- buf.push(map_results.filter(function(pair) {
- return pair[0] !== undefined && pair[1] !== undefined;
- }));
+ buf.push(toJSON(map_results));
} catch (err) {
if (err == "fatal_error") {
// Only if it's a "fatal_error" do we exit. What's a fatal error?
@@ -96,10 +94,10 @@
reason: "function raised fatal exception"};
}
print(toJSON({log: "function raised exception (" + err + ")"}));
- buf.push([]);
+ buf.push("[]");
}
}
- print(toJSON(buf));
+ print("[" + buf.join(", ") + "]");
break;
case "rereduce":
@@ -170,9 +168,18 @@
}
}
+function recursivelySeal(obj) {
+ seal(obj);
+ for (var propname in obj) {
+ if (typeof doc[propname] == "object") {
+ recursivelySeal(doc[propname]);
+ }
+ }
+}
+
function toJSON(val) {
if (typeof(val) == "undefined") {
- throw {error:"bad_value", reason:"Cannot encode 'undefined' value as JSON"};
+ throw "Cannot encode 'undefined' value as JSON";
}
var subs = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f',
'\r': '\\r', '"' : '\\"', '\\': '\\\\'};
Modified: incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_httpd.erl?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_httpd.erl (original)
+++ incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_httpd.erl Fri Jul 4 11:44:44 2008
@@ -116,9 +116,11 @@
"/_restart" ->
handle_restart_request(Req, Method);
"/_utils" ->
- {ok, Req:respond({301, [{"Location", "/_utils/"}], <<>>})};
+ {ok, Req:respond({301, [
+ {"Location", "/_utils/"}
+ ] ++ server_header(), <<>>})};
"/_utils/" ++ PathInfo ->
- {ok, Req:serve_file(PathInfo, DocumentRoot)};
+ {ok, Req:serve_file(PathInfo, DocumentRoot, server_header())};
"/_config/" ++ Config ->
handle_config_request(Req, Method, {config, Config});
"/_" ++ _Path ->
@@ -483,7 +485,7 @@
fun(_Key, _Red, {AccSeparator,AccSkip,AccCount}) when AccSkip > 0 ->
{ok, {AccSeparator,AccSkip-1,AccCount}};
(_Key, _Red, {AccSeparator,0,AccCount}) when AccCount == 0 ->
- {stop,{AccSeparator,0,AccCount}};
+ {ok, {AccSeparator,0,AccCount}};
(_Key, Red, {AccSeparator,0,AccCount}) when GroupLevel == 0 ->
Json = lists:flatten(cjson:encode({obj, [{key, null}, {value, Red}]})),
Resp:write_chunk(AccSeparator ++ Json),
@@ -633,9 +635,10 @@
throw({not_found, missing});
{Type, Bin} ->
Resp = Req:respond({200, [
- {"content-type", Type},
- {"content-length", integer_to_list(couch_doc:bin_size(Bin))}
- ], chunked}),
+ {"Cache-Control", "must-revalidate"},
+ {"Content-Type", Type},
+ {"Content-Length", integer_to_list(couch_doc:bin_size(Bin))}
+ ] ++ server_header(), chunked}),
couch_doc:bin_foldl(Bin,
fun(BinSegment, []) ->
ok = Resp:write_chunk(BinSegment),
@@ -722,6 +725,8 @@
Args#view_query_args{start_key=JsonKey,end_key=JsonKey};
{"startkey_docid", DocId} ->
Args#view_query_args{start_docid=DocId};
+ {"endkey_docid", DocId} ->
+ Args#view_query_args{end_docid=DocId};
{"startkey", Value} ->
Args#view_query_args{start_key=cjson:decode(Value)};
{"endkey", Value} ->
@@ -971,11 +976,11 @@
{500, error, Error}.
send_error(Req, {method_not_allowed, Methods}) ->
- {ok, Req:respond({405, [{"Allow", Methods}], <<>>})};
+ {ok, Req:respond({405, [{"Allow", Methods}] ++ server_header(), <<>>})};
send_error(Req, {modified, Etag}) ->
- {ok, Req:respond({412, [{"Etag", Etag}], <<>>})};
+ {ok, Req:respond({412, [{"Etag", Etag}] ++ server_header(), <<>>})};
send_error(Req, {not_modified, Etag}) ->
- {ok, Req:respond({304, [{"Etag", Etag}], <<>>})};
+ {ok, Req:respond({304, [{"Etag", Etag}] ++ server_header(), <<>>})};
send_error(Req, Error) ->
{Code, Json} = error_to_json(Error),
?LOG_INFO("HTTP Error (code ~w): ~p", [Code, Error]),
@@ -991,18 +996,23 @@
send_json(Req, Code, [], Value).
send_json(Req, Code, Headers, Value) ->
- ContentType = negotiate_content_type(Req),
+ DefaultHeaders = [
+ {"Content-Type", negotiate_content_type(Req)},
+ {"Cache-Control", "must-revalidate"}
+ ] ++ server_header(),
Body = cjson:encode(Value),
- Resp = Req:respond({Code, [{"Content-Type", ContentType}] ++ Headers,
- Body}),
+ Resp = Req:respond({Code, DefaultHeaders ++ Headers, Body}),
{ok, Resp}.
start_json_response(Req, Code) ->
start_json_response(Req, Code, []).
start_json_response(Req, Code, Headers) ->
- ContentType = negotiate_content_type(Req),
- Req:respond({Code, [{"Content-Type", ContentType}] ++ Headers, chunked}).
+ DefaultHeaders = [
+ {"Content-Type", negotiate_content_type(Req)},
+ {"Cache-Control", "must-revalidate"}
+ ] ++ server_header(),
+ Req:respond({Code, DefaultHeaders ++ Headers, chunked}).
end_json_response(Resp) ->
Resp:write_chunk(""),
@@ -1021,3 +1031,7 @@
true -> "application/json";
false -> "text/plain;charset=utf-8"
end.
+
+server_header() ->
+ [{"Server", "CouchDB/" ++ couch_server:get_version() ++
+ " (Erlang OTP/" ++ erlang:system_info(otp_release) ++ ")"}].
Modified: incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_util.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_util.erl?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_util.erl (original)
+++ incubator/couchdb/branches/runtimeconfig/src/couchdb/couch_util.erl Fri Jul 4 11:44:44 2008
@@ -41,7 +41,7 @@
case erl_ddll:load_driver(LibDir, "couch_erl_driver") of
ok -> ok;
{error, already_loaded} -> ok;
- Error -> exit(Error)
+ {error, Error} -> exit(erl_ddll:format_error(Error))
end.
new_uuid() ->
Modified: incubator/couchdb/branches/runtimeconfig/src/mochiweb/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/src/mochiweb/Makefile.am?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/src/mochiweb/Makefile.am (original)
+++ incubator/couchdb/branches/runtimeconfig/src/mochiweb/Makefile.am Fri Jul 4 11:44:44 2008
@@ -10,9 +10,7 @@
## License for the specific language governing permissions and limitations under
## the License.
-devdocdir = $(localdocdir)/developer/mochiweb
-
-mochiwebebindir = $(localerlanglibdir)/mochiweb-r76/ebin
+mochiwebebindir = $(localerlanglibdir)/mochiweb-r82/ebin
mochiwebebin_DATA = $(static_files) $(compiled_files)
Modified: incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_html.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_html.erl?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_html.erl (original)
+++ incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_html.erl Fri Jul 4 11:44:44 2008
@@ -101,7 +101,7 @@
to_html(Tokens) when is_list(Tokens) ->
to_html(Tokens, []).
-%% @spec escape(string() | binary()) -> string()
+%% @spec escape(string() | atom() | binary()) -> binary()
%% @doc Escape a string such that it's safe for HTML (amp; lt; gt;).
escape(B) when is_binary(B) ->
escape(binary_to_list(B), []);
@@ -110,7 +110,7 @@
escape(S) when is_list(S) ->
escape(S, []).
-%% @spec escape_attr(S::string()) -> string()
+%% @spec escape_attr(string() | binary() | atom() | integer() | float()) -> binary()
%% @doc Escape a string such that it's safe for HTML attrs
%% (amp; lt; gt; quot;).
escape_attr(B) when is_binary(B) ->
Modified: incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_request.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_request.erl?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_request.erl (original)
+++ incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_request.erl Fri Jul 4 11:44:44 2008
@@ -15,11 +15,11 @@
-export([send/1, recv/1, recv/2, recv_body/0, recv_body/1]).
-export([start_response/1, start_response_length/1, start_raw_response/1]).
-export([respond/1, ok/1]).
--export([not_found/0]).
+-export([not_found/0, not_found/1]).
-export([parse_post/0, parse_qs/0]).
-export([should_close/0, cleanup/0]).
-export([parse_cookie/0, get_cookie_value/1]).
--export([serve_file/2]).
+-export([serve_file/2, serve_file/3]).
-export([test/0]).
-define(SAVE_QS, mochiweb_request_qs).
@@ -276,9 +276,16 @@
Response.
%% @spec not_found() -> response()
-%% @doc respond({404, [{"Content-Type", "text/plain"}], "Not found."}).
+%% @doc Alias for <code>not_found([])</code>.
not_found() ->
- respond({404, [{"Content-Type", "text/plain"}], <<"Not found.">>}).
+ not_found([]).
+
+%% @spec not_found(ExtraHeaders) -> response()
+%% @doc Alias for <code>respond({404, [{"Content-Type", "text/plain"}
+%% | ExtraHeaders], <<"Not found.">>})</code>.
+not_found(ExtraHeaders) ->
+ respond({404, [{"Content-Type", "text/plain"} | ExtraHeaders],
+ <<"Not found.">>}).
%% @spec ok({value(), iodata()} | {value(), ioheaders(), iodata() | {file, IoDevice}}) ->
%% response()
@@ -326,7 +333,9 @@
%% unread data left on the socket, can't safely continue
orelse (DidNotRecv
andalso get_header_value("content-length") =/= undefined
- andalso list_to_integer(get_header_value("content-length")) > 0).
+ andalso list_to_integer(get_header_value("content-length")) > 0)
+ orelse (DidNotRecv
+ andalso get_header_value("transfer-encoding") =:= "chunked").
%% @spec cleanup() -> ok
%% @doc Clean up any junk in the process dictionary, required before continuing
@@ -455,9 +464,14 @@
%% @spec serve_file(Path, DocRoot) -> Response
%% @doc Serve a file relative to DocRoot.
serve_file(Path, DocRoot) ->
+ serve_file(Path, DocRoot, []).
+
+%% @spec serve_file(Path, DocRoot, ExtraHeaders) -> Response
+%% @doc Serve a file relative to DocRoot.
+serve_file(Path, DocRoot, ExtraHeaders) ->
case mochiweb_util:safe_relative_path(Path) of
undefined ->
- not_found();
+ not_found(ExtraHeaders);
RelPath ->
FullPath = filename:join([DocRoot, RelPath]),
File = case filelib:is_dir(FullPath) of
@@ -471,20 +485,23 @@
LastModified = httpd_util:rfc1123_date(FileInfo#file_info.mtime),
case get_header_value("if-modified-since") of
LastModified ->
- respond({304, [], ""});
+ respond({304, ExtraHeaders, ""});
_ ->
case file:open(File, [raw, binary]) of
{ok, IoDevice} ->
ContentType = mochiweb_util:guess_mime(File),
- Res = ok({ContentType, [{"last-modified", LastModified}], {file, IoDevice}}),
+ Res = ok({ContentType,
+ [{"last-modified", LastModified}
+ | ExtraHeaders],
+ {file, IoDevice}}),
file:close(IoDevice),
Res;
_ ->
- not_found()
+ not_found(ExtraHeaders)
end
end;
{error, _} ->
- not_found()
+ not_found(ExtraHeaders)
end
end.
Modified: incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_socket_server.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_socket_server.erl?rev=674105&r1=674104&r2=674105&view=diff
==============================================================================
--- incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_socket_server.erl (original)
+++ incubator/couchdb/branches/runtimeconfig/src/mochiweb/mochiweb_socket_server.erl Fri Jul 4 11:44:44 2008
@@ -96,6 +96,14 @@
gen_server:start_link(Name, ?MODULE, State, [])
end.
+ipv6_supported() ->
+ case (catch inet:getaddr("localhost", inet6)) of
+ {ok, _Addr} ->
+ true;
+ {error, _} ->
+ false
+ end.
+
init(State=#mochiweb_socket_server{ip=Ip, port=Port, backlog=Backlog}) ->
process_flag(trap_exit, true),
BaseOpts = [binary,
@@ -106,11 +114,16 @@
{active, false},
{nodelay, true}],
Opts = case Ip of
- any ->
- BaseOpts;
- Ip ->
- [{ip, Ip} | BaseOpts]
- end,
+ any ->
+ case ipv6_supported() of % IPv4, and IPv6 if supported
+ true -> [inet, inet6 | BaseOpts];
+ _ -> BaseOpts
+ end;
+ {_, _, _, _} -> % IPv4
+ [inet, {ip, Ip} | BaseOpts];
+ {_, _, _, _, _, _, _, _} -> % IPv6
+ [inet6, {ip, Ip} | BaseOpts]
+ end,
case gen_tcp_listen(Port, Opts, State) of
{stop, eacces} ->
case Port < 1024 of