Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A9D2B1818E for ; Tue, 22 Dec 2015 07:26:58 +0000 (UTC) Received: (qmail 19817 invoked by uid 500); 22 Dec 2015 07:26:58 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 19760 invoked by uid 500); 22 Dec 2015 07:26:58 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 19751 invoked by uid 99); 22 Dec 2015 07:26:58 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 22 Dec 2015 07:26:58 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 55DECE0007; Tue, 22 Dec 2015 07:26:58 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: kxepal@apache.org To: commits@couchdb.apache.org Date: Tue, 22 Dec 2015 07:26:58 -0000 Message-Id: <9444f7d80fd641c186f97842d9189a5c@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/2] documentation commit: updated refs/heads/master to a514a2b Repository: couchdb-documentation Updated Branches: refs/heads/master 09632eabb -> a514a2b9c COUCHDB-2874: Docs for JS rewrites COUCHDB-2874: Docs for JS rewrite Project: http://git-wip-us.apache.org/repos/asf/couchdb-documentation/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-documentation/commit/92cb6bfc Tree: http://git-wip-us.apache.org/repos/asf/couchdb-documentation/tree/92cb6bfc Diff: http://git-wip-us.apache.org/repos/asf/couchdb-documentation/diff/92cb6bfc Branch: refs/heads/master Commit: 92cb6bfc570679cb15aa9afe26471be6e0353963 Parents: 901f2f9 Author: ermouth Authored: Sat Dec 12 19:22:59 2015 +0300 Committer: ermouth Committed: Tue Dec 22 10:10:23 2015 +0300 ---------------------------------------------------------------------- src/api/ddoc/common.rst | 2 +- src/api/ddoc/rewrites.rst | 83 +++++++++++++++++++++++++++++++-- src/json-structure.rst | 41 ++++++++++++++++ src/query-server/protocol.rst | 95 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 216 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-documentation/blob/92cb6bfc/src/api/ddoc/common.rst ---------------------------------------------------------------------- diff --git a/src/api/ddoc/common.rst b/src/api/ddoc/common.rst index f8620c5..0bcb49a 100644 --- a/src/api/ddoc/common.rst +++ b/src/api/ddoc/common.rst @@ -52,7 +52,7 @@ * **options** (*object*): View's default options * **filters** (*object*): :ref:`Filter functions ` definition * **lists** (*object*): :ref:`List functions ` definition - * **rewrites** (*array*): Rewrite rules definition + * **rewrites** (*array* or *string*): Rewrite rules definition * **shows** (*object*): :ref:`Show functions ` definition * **updates** (*object*): :ref:`Update functions ` definition * **validate_doc_update** (*string*): :ref:`Validate document update http://git-wip-us.apache.org/repos/asf/couchdb-documentation/blob/92cb6bfc/src/api/ddoc/rewrites.rst ---------------------------------------------------------------------- diff --git a/src/api/ddoc/rewrites.rst b/src/api/ddoc/rewrites.rst index e0861e0..ccb3542 100644 --- a/src/api/ddoc/rewrites.rst +++ b/src/api/ddoc/rewrites.rst @@ -18,13 +18,88 @@ .. http:any:: /{db}/_design/{ddoc}/_rewrite/{path} :synopsis: Rewrites HTTP request for the specified path by using stored - routing rules + array of routing rules or javascript function Rewrites the specified path by rules defined in the specified design - document. + document. The rewrite rules are defined in *array* or *string* field + of the design document called ``rewrites``. - The rewrite rules are defined in *array* field of the design document - called ``rewrites``. Each rule is an *object* with next structure: +Rewrite section a is stringified function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + *'Rewrite using JS' feature was introduced in CouchDB 1.7*. If the + ``rewrites`` field is a stringified function, query server is used + to pre-process and route a request. + + The function receives truncated version of req object as a single argument + and must return object, containing new information about request. + + Returned object should include properties as: + + - **path** (*string*): Rewritten path, mandatory if no *code* provided + - **query** (*array*): Rewritten query, if omitted original query keys + are used + - **headers** (*object*): Rewritten headers. If omitted, original + request headers are used + - **method** (*string*): Method of rewritten request. If omitted, + original request method is used + - **code** (*number*): Returned code. If provided, request is not rewritten + and user immidiately receives response with the code + - **body** (*string*): Body for POST/PUT requests, or for returning to user + if *code* field provided. If POST/PUT request is being rewritten and no + body returned by rewrite function, original request body is used + + **Example A**. Restricting access. + + .. code-block:: javascript + + function(req2) { + var path = req2.path.slice(4), + isWrite = /^(put|post|delete)$/i.test(req2.method), + isFin = req2.userCtx.roles.indexOf("finance")>-1; + if (path[0] == "finance" && isWrite && !isFin) { + // Deny writes to DB "finance" for users + // having no "finance" role + return { + code: 403, + body:JSON.stringify({ + error:"forbidden". + reason:"You are not allowed to modify docs in this DB" + }) + } + } + // Pass through all other requests + return {path:"../../../"+path.join("/")} + } + + **Example B**. Different replies for JSON and HTML requests. + + .. code-block:: javascript + + function(req2) { + var path = req2.path.slice(4), + h = headers, + wantsJson = (h.Accept||"").indexOf("application/json")>-1, + reply = {}; + if (!wantsJson) { + // Here we should prepare reply object + // for plain HTML pages + } else { + // Pass through JSON requests + reply.path = "../../../"+path.join("/"); + } + return reply; + } + + The req2 object rewrites is called with is a slightly truncated version + of req object, provided for list and update functions. Fields *info*, + *uuid*, *id* and *form* are removed to speed up request processing. + All other fields of the req object are in place. + +Rewrite section is an array +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Each rule is an *object* with next structure: - **from** (*string*): The path rule used to bind current uri to the rule. It use pattern matching for that http://git-wip-us.apache.org/repos/asf/couchdb-documentation/blob/92cb6bfc/src/json-structure.rst ---------------------------------------------------------------------- diff --git a/src/json-structure.rst b/src/json-structure.rst index aa4b5af..6075120 100644 --- a/src/json-structure.rst +++ b/src/json-structure.rst @@ -449,6 +449,47 @@ Request object "uuid": "3184f9d1ea934e1f81a24c71bde5c168" } +.. _request2_object: + +Request2 object +=============== + ++--------------------------------+---------------------------------------------+ +| Field | Description | ++================================+=============================================+ +| body | Request body data as `string`. | +| | If the request method is `GET` this field | +| | contains the value ``"undefined"``. If the | +| | method is `DELETE` or `HEAD` the value is | +| | ``""`` (empty string). | ++--------------------------------+---------------------------------------------+ +| cookie | Cookies `object`. | ++--------------------------------+---------------------------------------------+ +| headers | Request headers `object`. | ++--------------------------------+---------------------------------------------+ +| method | Request method as `string` or `array`. | +| | String value is a method as one of: `HEAD`, | +| | `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`, | +| | and `TRACE`. Otherwise it will be | +| | represented as an array of char codes. | ++--------------------------------+---------------------------------------------+ +| path | List of requested path sections. | ++--------------------------------+---------------------------------------------+ +| peer | Request source IP address. | ++--------------------------------+---------------------------------------------+ +| query | URL query parameters `object`. | +| | Note that multiple keys are not supported | +| | and the last key value suppresses others. | ++--------------------------------+---------------------------------------------+ +| requested_path | List of actual requested path section. | ++--------------------------------+---------------------------------------------+ +| raw_path | Raw requested path `string`. | ++--------------------------------+---------------------------------------------+ +| secObj | :ref:`security_object`. | ++--------------------------------+---------------------------------------------+ +| userCtx | :ref:`userctx_object`. | ++--------------------------------+---------------------------------------------+ + .. _response_object: Response object http://git-wip-us.apache.org/repos/asf/couchdb-documentation/blob/92cb6bfc/src/query-server/protocol.rst ---------------------------------------------------------------------- diff --git a/src/query-server/protocol.rst b/src/query-server/protocol.rst index 9b8382c..fb619ef 100644 --- a/src/query-server/protocol.rst +++ b/src/query-server/protocol.rst @@ -860,6 +860,101 @@ The Query Server answers:: ``unauthorized`` - these errors will be turned into correct ``HTTP 403`` and ``HTTP 401`` responses respectively. +.. _qs/ddoc/rewrites: + +``rewrites`` +----------------------- + +:Command: ``ddoc`` +:SubCommand: ``rewrites`` +:Arguments: + + - :ref:`request2_object` + +:Returns: ``1`` + +Executes :ref:`rewrite function `. + +CouchDB send:: + + [ + "ddoc", + "_design/id", + ["rewrites"], + [ + { + "method": "POST", + "requested_path": [ + "test", + "_design", + "1139", + "_update", + "nothing" + ], + "path": [ + "test", + "_design", + "1139", + "_update", + "nothing" + ], + "raw_path": "/test/_design/1139/_update/nothing", + "query": {}, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity, gzip, deflate, compress", + "Content-Length": "0", + "Host": "localhost:5984" + }, + "body": "", + "peer": "127.0.0.1", + "cookie": {}, + "userCtx": { + "db": "test", + "name": null, + "roles": [ + "_admin" + ] + }, + "secObj": {} + } + ] + ] + +The Query Server answers:: + + [ + "ok", + { + "path": "some/path", + "query": {"key1": "value1", "key2": "value2"}, + "method": "METHOD", + "headers": {"Header1": "value1", "Header2": "value2"}, + "body": "" + } + ] + +or in case of direct response:: + + [ + "ok", + { + "headers": {"Content-Type": "text/plain"}, + "body": "Welcome!", + "code": 200 + } + ] + +or for immidiate redirect:: + + [ + "ok", + { + "headers": {"Location": "http://example.com/path/"}, + "code": 302 + } + ] + .. _qs/errors: Raising errors