Skip to content

Commit

Permalink
Merge from trunk. Test failures in list_views need to be fixed.
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/rep_security@753413 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Damien F. Katz committed Mar 13, 2009
1 parent 0059ec7 commit 258b343
Show file tree
Hide file tree
Showing 34 changed files with 1,390 additions and 678 deletions.
7 changes: 7 additions & 0 deletions CHANGES
Expand Up @@ -17,6 +17,13 @@ Futon Utility Client:
* Added pagination to the database listing page.
* Implemented attachment uploading from the document page.

Design Document Resource Paths:

* Added httpd_design_handlers config section.
* Moved _view to httpd_design_handlers.
* Added ability to render documents as non-JSON content-types with _show and
_list functions, which are also httpd_design_handlers.

Version 0.8.1-incubating
------------------------

Expand Down
2 changes: 1 addition & 1 deletion bin/couchdb.tpl.in
Expand Up @@ -207,7 +207,7 @@ start_couchdb () {
export HEART_COMMAND
export HEART_BEAT_TIMEOUT
`eval $command -pidfile $PID_FILE -heart \
> $STDOUT_FILE 2> $STDERR_FILE` || true
>> $STDOUT_FILE 2>> $STDERR_FILE` || true
PID=`_get_pid`
if test -n "$PID"; then
if kill -0 $PID 2> /dev/null; then
Expand Down
11 changes: 7 additions & 4 deletions etc/couchdb/default.ini.tpl.in
Expand Up @@ -8,7 +8,7 @@ view_index_dir = %localstatelibdir%
util_driver_dir = %couchprivlibdir%
max_document_size = 4294967296 ; 4 GB
max_attachment_chunk_size = 4294967296 ; 4GB
view_timeout = 5000 ; 5 seconds
os_process_timeout = 5000 ; 5 seconds. for view and external servers.
max_dbs_open = 100

[httpd]
Expand Down Expand Up @@ -52,13 +52,16 @@ _restart = {couch_httpd_misc_handlers, handle_restart_req}
_stats = {couch_httpd_stats_handlers, handle_stats_req}

[httpd_db_handlers]
_view = {couch_httpd_view, handle_view_req}
_design = {couch_httpd_db, handle_design_req}
_temp_view = {couch_httpd_view, handle_temp_view_req}
_show = {couch_httpd_show, handle_doc_show_req}
_list = {couch_httpd_show, handle_view_list_req}

; The external module takes an optional argument allowing you to narrow it to a
; single script. Otherwise the script name is inferred from the first path section
; after _external's own path.
; _mypath = {couch_httpd_external, handle_external_req, <<"mykey">>}
; _external = {couch_httpd_external, handle_external_req}

[httpd_design_handlers]
_view = {couch_httpd_view, handle_view_req}
_show = {couch_httpd_show, handle_doc_show_req}
_list = {couch_httpd_show, handle_view_list_req}
5 changes: 2 additions & 3 deletions share/server/main.js
Expand Up @@ -364,10 +364,9 @@ while (cmd = eval(readline())) {
var row_info = row_line[listFun];
runRenderFunction(listFun, [null, row, req, row_info]);
if (row_info.first_key == null) {
row_info.first_key = row.key;
} else {
row_info.prev_key = row.key;
row_info.first_key = row.key;
}
row_info.prev_key = row.key;
row_info.row_number++;
row_line[listFun] = row_info;
break;
Expand Down
7 changes: 6 additions & 1 deletion share/www/database.html
Expand Up @@ -39,7 +39,12 @@
$(function() {
if (page.redirecting) return;
$("h1 strong").text(page.db.name);
var viewPath = (page.viewName || "_all_docs").replace(/^_design\//, "_view/");
var viewPath = page.viewName || "_all_docs";
if (/^_design\//.test(viewPath)) {
var parts = viewPath.split("/");
parts.splice(2, 0, "_view");
viewPath = parts.join("/");
}
if (viewPath != "_temp_view" && viewPath != "_design_docs") {
$("h1 a.raw").attr("href", "/" + encodeURIComponent(page.db.name) +
"/" + viewPath);
Expand Down
1 change: 0 additions & 1 deletion share/www/index.html
Expand Up @@ -63,7 +63,6 @@ <h1><strong>Overview</strong></h1>
<tr>
<th>Name</th>
<th class="size">Size</th>
<th class="apps">Applications</th>
<th class="count">Number of Documents</th>
<th class="seq">Update Seq</th>
</tr>
Expand Down
12 changes: 6 additions & 6 deletions share/www/script/couch.js
Expand Up @@ -153,12 +153,13 @@ function CouchDB(name, httpHeaders) {
}

this.view = function(viewname, options, keys) {
var viewParts = viewname.split('/');
var viewPath = this.uri + "_design/" + viewParts[0] + "/_view/"
+ viewParts[1] + encodeOptions(options);
if(!keys) {
this.last_req = this.request("GET", this.uri + "_view/" +
viewname + encodeOptions(options));
this.last_req = this.request("GET", viewPath);
} else {
this.last_req = this.request("POST", this.uri + "_view/" +
viewname + encodeOptions(options), {
this.last_req = this.request("POST", viewPath, {
headers: {"Content-Type": "application/json"},
body: JSON.stringify({keys:keys})
});
Expand Down Expand Up @@ -310,10 +311,9 @@ CouchDB.getVersion = function() {
CouchDB.replicate = function(source, target, rep_options) {
rep_options = rep_options || {};
var headers = rep_options.headers || {};
var options = rep_options.options || {};
CouchDB.last_req = CouchDB.request("POST", "/_replicate", {
headers: headers,
body: JSON.stringify({source: source, target: target, options: options})
body: JSON.stringify({source: source, target: target})
});
CouchDB.maybeThrowError(CouchDB.last_req);
return JSON.parse(CouchDB.last_req.responseText);
Expand Down
1 change: 1 addition & 0 deletions share/www/script/couch_tests.js
Expand Up @@ -41,6 +41,7 @@ loadTest("multiple_rows.js");
loadTest("large_docs.js");
loadTest("utf8.js");
loadTest("attachments.js");
loadTest("attachment_names.js");
loadTest("attachment_paths.js");
loadTest("attachment_views.js");
loadTest("design_paths.js");
Expand Down
11 changes: 2 additions & 9 deletions share/www/script/futon.browse.js
Expand Up @@ -52,16 +52,9 @@
$("#databases tbody.content").append("<tr>" +
"<th><a href='database.html?" + encodeURIComponent(dbName) + "'>" +
dbName + "</a></th>" +
"<td class='size'></td><td class='apps'></td><td class='count'></td>" +
"<td class='size'></td><td class='count'></td>" +
"<td class='seq'></td></tr>");
var db = $.couch.db(dbName);
db.allApps({
eachApp : function(name, path) {
$("#databases tbody.content tr:eq(" + idx + ")")
.find("td.apps").append('<a href="'+path+'">'+name+'</a> ');
}
});
db.info({
$.couch.db(dbName).info({
success: function(info) {
$("#databases tbody.content tr:eq(" + idx + ")")
.find("td.size").text($.futon.formatSize(info.disk_size)).end()
Expand Down
7 changes: 4 additions & 3 deletions share/www/script/jquery.couch.js
Expand Up @@ -191,9 +191,9 @@
appName = appName.join('/');
index = ddoc.couchapp && ddoc.couchapp.index;
if (index) {
appPath = ['', name, index[0], appName, index[1]].join('/');
appPath = ['', name, ddoc._id, index].join('/');
} else if (ddoc._attachments && ddoc._attachments["index.html"]) {
appPath = ['', name, '_design', appName, "index.html"].join('/');
appPath = ['', name, ddoc._id, "index.html"].join('/');
}
if (appPath) options.eachApp(appName, appPath, ddoc);
}
Expand Down Expand Up @@ -298,8 +298,9 @@
},
view: function(name, options) {
options = options || {};
name = name.split('/');
$.ajax({
type: "GET", url: this.uri + "_view/" + name + encodeOptions(options),
type: "GET", url: this.uri + "_design/" + name[0] + "/_view/" + name[1] + encodeOptions(options),
dataType: "json",
complete: function(req) {
var resp = $.httpData(req, "json");
Expand Down
87 changes: 87 additions & 0 deletions share/www/script/test/attachment_names.js
@@ -0,0 +1,87 @@
// 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.

couchTests.attachment_names = function(debug) {
var db = new CouchDB("test_suite_db");
db.deleteDb();
db.createDb();
if (debug) debugger;

var binAttDoc = {
_id: "bin_doc",
_attachments:{
"foo\x80txt": {
content_type:"text/plain",
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
}

// inline attachments
try {
db.save(binAttDoc);
TEquals(1, 2, "Attachment name with non UTF-8 encoding saved. Should never show!");
} catch (e) {
TEquals("bad_request", e.error, "attachment_name: inline attachments");
TEquals("Attachment name is not UTF-8 encoded", e.reason, "attachment_name: inline attachments");
}


// standalone docs
var bin_data = "JHAPDO*AU£PN ){(3u[d 93DQ9¡€])} ææøo'∂ƒæ≤çæππ•¥∫¶®#†π¶®¥π€ª®˙π8np";

var xhr = (CouchDB.request("PUT", "/test_suite_db/bin_doc3/attachment\x80txt", {
headers:{"Content-Type":"text/plain;charset=utf-8"},
body:bin_data
}));

var resp = JSON.parse(xhr.responseText);
TEquals(400, xhr.status, "attachment_name: standalone API");
TEquals("bad_request", resp.error, "attachment_name: standalone API");
TEquals("Attachment name is not UTF-8 encoded", resp.reason, "attachment_name: standalone API");


// bulk docs
var docs = { docs: [binAttDoc] };

var xhr = CouchDB.request("POST", "/test_suite_db/_bulk_docs", {
body: JSON.stringify(docs)
});

var resp = JSON.parse(xhr.responseText);
TEquals(400, xhr.status, "attachment_name: bulk docs");
TEquals("bad_request", resp.error, "attachment_name: bulk docs");
TEquals("Attachment name is not UTF-8 encoded", resp.reason, "attachment_name: bulk docs");


// leading underscores
var binAttDoc = {
_id: "bin_doc2",
_attachments:{
"_foo.txt": {
content_type:"text/plain",
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
}

try {
db.save(binAttDoc);
TEquals(1, 2, "Attachment name with leading underscore saved. Should never show!");
} catch (e) {
TEquals("bad_request", e.error, "attachment_name: leading underscore");
TEquals("Attachment name can't start with '_'", e.reason, "attachment_name: leading underscore");
}

// todo: form uploads, waiting for cmlenz' test case for form uploads

};
8 changes: 4 additions & 4 deletions share/www/script/test/etags_views.js
Expand Up @@ -45,20 +45,20 @@ couchTests.etags_views = function(debug) {
db.bulkSave(docs);

// verify get w/Etag on map view
xhr = CouchDB.request("GET", "/test_suite_db/_view/etags/basicView");
xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView");
T(xhr.status == 200);
var etag = xhr.getResponseHeader("etag");
xhr = CouchDB.request("GET", "/test_suite_db/_view/etags/basicView", {
xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView", {
headers: {"if-none-match": etag}
});
T(xhr.status == 304);
// TODO GET with keys (when that is available)

// reduce view
xhr = CouchDB.request("GET", "/test_suite_db/_view/etags/withReduce");
xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/withReduce");
T(xhr.status == 200);
var etag = xhr.getResponseHeader("etag");
xhr = CouchDB.request("GET", "/test_suite_db/_view/etags/withReduce", {
xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/withReduce", {
headers: {"if-none-match": etag}
});
T(xhr.status == 304);
Expand Down

0 comments on commit 258b343

Please sign in to comment.