.. 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.

.. _api/ddoc/rewrite:

========================================
``/db/_design/design-doc/_rewrite/path``
========================================

.. http:any:: /{db}/_design/{ddoc}/_rewrite/{path}
    :synopsis: Rewrites HTTP request for the specified path by using stored
               array of routing rules or JavaScript function

    Rewrites the specified path by rules defined in the specified design
    document. The rewrite rules are defined by the ``rewrites`` field of the
    design document. The ``rewrites`` field can either be a *string* containing
    the a rewrite function or an *array* of rule definitions.

Using a stringified function for ``rewrites``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. versionadded:: 2.0

    When the ``rewrites`` field is a stringified function, the query server is used
    to pre-process and route requests.

    The function takes a :ref:`request2_object`.

    The return value of the function will cause the server to rewrite the
    request to a new location or immediately return a response.

    To rewrite the request, return an object containing the following
    properties:

    - **path** (*string*): Rewritten path.
    - **query** (*array*): Rewritten query. If omitted, the original
      query keys are used.
    - **headers** (*object*): Rewritten headers. If omitted, the original
      request headers are used.
    - **method** (*string*): HTTP method of rewritten request (``"GET"``,
      ``"POST"``, etc). If omitted, the original request method is used.
    - **body** (*string*): Body for ``"POST"``/``"PUT"`` requests. If omitted,
      the original request body is used.

    To immediately respond to the request, return an object containing the
    following properties:

    - **code** (*number*): Returned HTTP status code (``200``, ``404``, etc).
    - **body** (*string*): Body of the response to user.

    **Example A**. Restricting access.

    .. code-block:: javascript

        function(req2) {
          var path = req2.path.slice(4),
            isWrite = /^(put|post|delete)$/i.test(req2.method),
            isFinance = req2.userCtx.roles.indexOf("finance") > -1;
          if (path[0] == "finance" && isWrite && !isFinance) {
            // 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;
        }

Using an array of rules for ``rewrites``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    When the ``rewrites`` field is an array of rule objects, the server will
    rewrite the request based on the first matching rule in the array.

    Each rule in the array is an *object* with the following fields:

    - **method** (*string*): HTTP request method to bind the request method to
      the rule. If omitted, uses ``"*"``, which matches all methods.
    - **from** (*string*): The pattern used to compare against the URL and
      define dynamic variables.
    - **to** (*string*): The path to rewrite the URL to. It can contain
      variables depending on binding variables discovered during pattern
      matching and query args (URL args and from the query member).
    - **query** (*object*): Query args passed to the rewritten URL. They may
      contain dynamic variables.

    The ``to`` and ``from`` paths may contains string patterns with leading
    ``:`` or ``*`` characters to define dynamic variables in the match.

    The first rule in the ``rewrites`` array that matches the incoming request
    is used to define the rewrite. To match the incoming request, the
    rule's ``method`` must match the request's HTTP method and the rule's
    ``from`` must match the request's path using the following pattern matching
    logic.

    - The *from* pattern and URL are first split on ``/`` to get a list of
      tokens. For example, if *from* field is ``/somepath/:var/*`` and the URL
      is ``/somepath/a/b/c``, the tokens are ``somepath``, ``:var``, and
      ``*`` for the *from* pattern and ``somepath``, ``a``, ``b``, and
      ``c`` for the URL.
    - Each token starting with ``:`` in the pattern will match the
      corresponding token in the URL and define a new dynamic variable whose
      name is the remaining string after the ``:`` and value is the token from
      the URL. In this example, the ``:var`` token will match ``b``
      and set ``var`` = ``a``.
    - The star token ``*`` in the pattern will match any number of tokens in
      the URL and must be the last token in the pattern. It will define a
      dynamic variable with the remaining tokens. In this example, the ``*``
      token will match the ``b`` and ``c`` tokens and set ``*`` =
      ``b/c``.
    - The remaining tokens must match exactly for the pattern to be considered
      a match. In this example, ``somepath`` in the pattern matches
      ``somepath`` in the URL and all tokens in the URL have matched, causing
      this rule to be a match.

    Once a rule is found, the request URL is rewritten using the ``to`` and
    ``query`` fields. Dynamic variables are substituted into the ``:`` and
    ``*`` variables in these fields to produce the final URL.

    If no rule matches, a :statuscode:`404` response is returned.

    Examples:

    +-----------------------------------+----------+------------------+-------+
    |               Rule                |    URL   |  Rewrite to      | Tokens|
    +===================================+==========+==================+=======+
    | {"from": "/a",                    | /a       | /some            |       |
    |  "to": "/some"}                   |          |                  |       |
    +-----------------------------------+----------+------------------+-------+
    | {"from": "/a/\*",                 | /a/b/c   | /some/b/c        |       |
    |  "to": "/some/\*}                 |          |                  |       |
    +-----------------------------------+----------+------------------+-------+
    | {"from": "/a/b",                  | /a/b?k=v | /some?k=v        | k=v   |
    |  "to": "/some"}                   |          |                  |       |
    +-----------------------------------+----------+------------------+-------+
    | {"from": "/a/b",                  | /a/b     | /some/b?var=b    | var=b |
    |  "to": "/some/:var"}              |          |                  |       |
    +-----------------------------------+----------+------------------+-------+
    | {"from": "/a/:foo/",              | /a/b/c   | /some/b/c?foo=b  | foo=b |
    |  "to": "/some/:foo/"}             |          |                  |       |
    +-----------------------------------+----------+------------------+-------+
    | {"from": "/a/:foo",               | /a/b     | /some/?k=b&foo=b | foo=b |
    |  "to": "/some",                   |          |                  |       |
    |  "query": { "k": ":foo" }}        |          |                  |       |
    +-----------------------------------+----------+------------------+-------+
    | {"from": "/a",                    | /a?foo=b | /some/?b&foo=b   | foo=b |
    |  "to": "/some/:foo"}              |          |                  |       |
    +-----------------------------------+----------+------------------+-------+

    Request method, header, query parameters, request payload and response body
    are dependent on the endpoint to which the URL will be rewritten.

    :param db: Database name
    :param ddoc: Design document name
    :param path: URL path to rewrite
