couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian Jenkins <br...@brianjenkins.org>
Subject Patch: X-HTTP-METHOD-OVERRIDE header support
Date Thu, 10 Jun 2010 19:59:00 GMT
Hello.

Please excuse my Erlang -- I've learned just enough to hack in support
for X-HTTP-METHOD-OVERRIDE headers.

Also available in the trunk and 0.11.x branches here:
http://github.com/bonkydog/couchdb

Best,
Brian

---
 share/Makefile.am                        |    1 +
 share/www/script/couch_tests.js          |    1 +
 share/www/script/test/method_override.js |   36 ++++++++++++++++++++++++++++++
 src/couchdb/couch_httpd.erl              |   12 ++++++++-
 4 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 share/www/script/test/method_override.js

diff --git a/share/Makefile.am b/share/Makefile.am
index 1622130..cb9aae2 100644
--- a/share/Makefile.am
+++ b/share/Makefile.am
@@ -136,6 +136,7 @@ nobase_dist_localdata_DATA = \
    www/script/test/lorem.txt \
    www/script/test/lorem_b64.txt \
    www/script/test/lots_of_docs.js \
+    www/script/test/method_override.js \
    www/script/test/multiple_rows.js \
    www/script/test/oauth.js \
    www/script/test/proxyauth.js \
diff --git a/share/www/script/couch_tests.js b/share/www/script/couch_tests.js
index 4225ce7..4f0d282 100644
--- a/share/www/script/couch_tests.js
+++ b/share/www/script/couch_tests.js
@@ -58,6 +58,7 @@ loadTest("jsonp.js");
 loadTest("large_docs.js");
 loadTest("list_views.js");
 loadTest("lots_of_docs.js");
+loadTest("method_override.js");
 loadTest("multiple_rows.js");
 loadScript("script/oauth.js");
 loadScript("script/sha1.js");
diff --git a/share/www/script/test/method_override.js
b/share/www/script/test/method_override.js
new file mode 100644
index 0000000..bc4d52f
--- /dev/null
+++ b/share/www/script/test/method_override.js
@@ -0,0 +1,36 @@
+// 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.
+
+// Allow broken HTTP clients to fake a full method vocabulary with an
X-HTTP-METHOD-OVERRIDE header
+couchTests.method_override = function(debug) {
+  var result = JSON.parse(CouchDB.request("GET", "/").responseText);
+  T(result.couchdb == "Welcome");
+
+  var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"});
+  db.deleteDb();
+
+  db.createDb();
+
+  var doc = {bob : "connie"};
+  xhr = CouchDB.request("POST", "/test_suite_db/fnord", {body:
JSON.stringify(doc), headers:{"Method-Override" : "PUT"}});
+  T(xhr.status == 201);
+
+  doc = db.open("fnord");
+  T(doc.bob == "connie");
+
+  xhr = CouchDB.request("POST", "/test_suite_db/fnord?rev=" +
doc._rev, {headers:{"Method-Override" : "DELETE"}});
+  T(xhr.status == 200)
+
+  doc = db.open("fnord");
+  T(doc == null);
+
+};
\ No newline at end of file
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index a8f0bb5..558149f 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -218,9 +218,17 @@ handle_request_int(MochiReq, DefaultFun,
        Meth -> couch_util:to_existing_atom(Meth)
    end,
    increment_method_stats(Method1),
+
+    % allow broken HTTP clients to fake a full method vocabulary with
an X-HTTP-METHOD-OVERRIDE header
+    MethodOverride = MochiReq:get_primary_header_value("Method-Override"),
+    Method2 = case lists:member(MethodOverride, ["GET", "HEAD",
"POST", "PUT", "DELETE", "TRACE", "CONNECT"]) of
+        true -> ?LOG_INFO("MethodOverride: ~s (real method was ~s)",
[MethodOverride, Method1]), list_to_atom(MethodOverride);
+        _ -> Method1
+    end,
+
    % alias HEAD to GET as mochiweb takes care of stripping the body
-    Method = case Method1 of
-        'HEAD' -> 'GET';
+    Method = case Method2 of
+            'HEAD' -> 'GET';
        Other -> Other
    end,

--
1.7.1

Mime
View raw message