Full Code of restify/node-restify for AI

master 009f40b31612 cached
193 files
998.8 KB
249.3k tokens
160 symbols
1 requests
Download .txt
Showing preview only (1,054K chars total). Download the full file or copy to clipboard to get everything.
Repository: restify/node-restify
Branch: master
Commit: 009f40b31612
Files: 193
Total size: 998.8 KB

Directory structure:
gitextract_6dd12z3s/

├── .dir-locals.el
├── .eslintignore
├── .eslintrc.js
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1-bug-report.md
│   │   └── 2-feature-request.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── stale.yml
│   └── workflows/
│       ├── ci.yml
│       └── release-please.yml
├── .gitignore
├── .npmignore
├── .prettierignore
├── .prettierrc
├── .tern-project
├── CHANGELOG.md
├── CHANGES.md
├── CONTRIBUTING.md
├── FEATURE_REQUESTS.md
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── benchmark/
│   ├── benchmarks/
│   │   ├── middleware.js
│   │   ├── response-json.js
│   │   ├── response-text.js
│   │   └── router-heavy.js
│   ├── index.js
│   ├── lib/
│   │   ├── autocannon.js
│   │   └── bench.js
│   └── package.json
├── bin/
│   └── report-latency
├── docs/
│   ├── _api/
│   │   ├── formatters.md
│   │   ├── plugins.md
│   │   ├── request.md
│   │   ├── response.md
│   │   └── server.md
│   ├── api/
│   │   ├── formatters-usage.md
│   │   ├── plugins-usage.md
│   │   ├── request-events.md
│   │   ├── request-log.md
│   │   ├── server-errors.md
│   │   └── server-events.md
│   ├── config/
│   │   ├── formatters.yaml
│   │   ├── plugins.yaml
│   │   ├── request.yaml
│   │   └── server.yaml
│   ├── guides/
│   │   ├── 4TO5GUIDE.md
│   │   ├── 6to7guide.md
│   │   ├── 8to9guide.md
│   │   ├── client.md
│   │   ├── dtrace.md
│   │   └── server.md
│   └── index.md
├── examples/
│   ├── dtrace/
│   │   ├── demo.js
│   │   ├── handler-timing.d
│   │   └── hello.js
│   ├── example.js
│   ├── http2/
│   │   ├── http2.js
│   │   └── keys/
│   │       ├── http2-cert.pem
│   │       ├── http2-csr.pem
│   │       └── http2-key.pem
│   ├── jsonp/
│   │   └── jsonp.js
│   ├── sockio/
│   │   ├── package.json
│   │   └── sockio.js
│   ├── spdy/
│   │   ├── keys/
│   │   │   ├── spdy-cert.pem
│   │   │   ├── spdy-csr.pem
│   │   │   └── spdy-key.pem
│   │   └── spdy.js
│   └── todoapp/
│       ├── README.md
│       ├── lib/
│       │   ├── client.js
│       │   ├── index.js
│       │   └── server.js
│       ├── main.js
│       ├── package.json
│       └── test/
│           └── todo.test.js
├── lib/
│   ├── chain.js
│   ├── deprecationWarnings.js
│   ├── dtrace.js
│   ├── errorTypes.js
│   ├── formatters/
│   │   ├── binary.js
│   │   ├── index.js
│   │   ├── json.js
│   │   ├── jsonp.js
│   │   └── text.js
│   ├── helpers/
│   │   └── chainComposer.js
│   ├── http_date.js
│   ├── index.js
│   ├── plugins/
│   │   ├── accept.js
│   │   ├── audit.js
│   │   ├── authorization.js
│   │   ├── bodyParser.js
│   │   ├── bodyReader.js
│   │   ├── conditionalHandler.js
│   │   ├── conditionalRequest.js
│   │   ├── cpuUsageThrottle.js
│   │   ├── date.js
│   │   ├── fieldedTextBodyParser.js
│   │   ├── formBodyParser.js
│   │   ├── fullResponse.js
│   │   ├── gzip.js
│   │   ├── index.js
│   │   ├── inflightRequestThrottle.js
│   │   ├── jsonBodyParser.js
│   │   ├── jsonp.js
│   │   ├── metrics.js
│   │   ├── multipartBodyParser.js
│   │   ├── oauth2TokenParser.js
│   │   ├── pre/
│   │   │   ├── context.js
│   │   │   ├── dedupeSlashes.js
│   │   │   ├── pause.js
│   │   │   ├── prePath.js
│   │   │   ├── reqIdHeaders.js
│   │   │   ├── strictQueryParams.js
│   │   │   └── userAgent.js
│   │   ├── query.js
│   │   ├── requestExpiry.js
│   │   ├── requestLogger.js
│   │   ├── static.js
│   │   ├── staticFiles.js
│   │   ├── throttle.js
│   │   └── utils/
│   │       ├── hrTimeDurationInMs.js
│   │       ├── httpDate.js
│   │       ├── regex.js
│   │       └── shallowCopy.js
│   ├── request.js
│   ├── response.js
│   ├── router.js
│   ├── routerRegistryRadix.js
│   ├── server.js
│   ├── upgrade.js
│   └── utils.js
├── package.json
├── test/
│   ├── .eslintrc
│   ├── chain.test.js
│   ├── chainComposer.test.js
│   ├── formatter-optional.test.js
│   ├── formatter.test.js
│   ├── index.test.js
│   ├── keys/
│   │   ├── http2-cert.pem
│   │   ├── http2-csr.pem
│   │   └── http2-key.pem
│   ├── lib/
│   │   ├── helper.js
│   │   ├── server-withDisableUncaughtException.js
│   │   └── streamRecorder.js
│   ├── plugins/
│   │   ├── .eslintrc
│   │   ├── accept.test.js
│   │   ├── audit.test.js
│   │   ├── authorization.test.js
│   │   ├── bodyReader.test.js
│   │   ├── conditionalHandler.test.js
│   │   ├── conditionalRequest.test.js
│   │   ├── context.test.js
│   │   ├── cpuUsageThrottle.test.js
│   │   ├── dedupeSlashes.test.js
│   │   ├── fieldedTextParser.test.js
│   │   ├── files/
│   │   │   ├── data-csv.txt
│   │   │   ├── data-tsv.txt
│   │   │   ├── object-csv.json
│   │   │   └── object-tsv.json
│   │   ├── formBodyParser.test.js
│   │   ├── gzip.test.js
│   │   ├── inflightRequestThrottle.test.js
│   │   ├── jsonBodyParser.test.js
│   │   ├── metrics.test.js
│   │   ├── multipart.test.js
│   │   ├── oauth2.test.js
│   │   ├── plugins.test.js
│   │   ├── query.test.js
│   │   ├── reqIdHeaders.test.js
│   │   ├── requestExpiry.test.js
│   │   ├── static.test.js
│   │   ├── staticFiles.test.js
│   │   ├── strictQueryParams.test.js
│   │   ├── testStaticFiles/
│   │   │   ├── docs/
│   │   │   │   ├── doc.md
│   │   │   │   └── index.html
│   │   │   ├── file1.txt
│   │   │   ├── index.html
│   │   │   └── special/
│   │   │       └── $_$/
│   │   │           └── bad (file).txt
│   │   ├── throttle.test.js
│   │   ├── userAgent.test.js
│   │   └── utilsHrTimeDurationInMs.test.js
│   ├── request.test.js
│   ├── response.test.js
│   ├── router.test.js
│   ├── routerRegistryRadix.test.js
│   ├── server.test.js
│   ├── serverHttp2.test.js
│   ├── upgrade.test.js
│   └── utils.test.js
└── tools/
    ├── docsBuild.js
    └── mk/
        ├── Makefile.defs
        ├── Makefile.deps
        └── Makefile.targ

================================================
FILE CONTENTS
================================================

================================================
FILE: .dir-locals.el
================================================
((nil . ((indent-tabs-mode . nil)
         (tab-width . 4)
         (fill-column . 80)))
 (js-mode . ((js-indent-level . 4)
             (indent-tabs-mode . nil)
             )))


================================================
FILE: .eslintignore
================================================
# node_modules ignored by default
node_modules/

# other ignored directories
bin/
deps/
docs/
examples/
cover_html/



================================================
FILE: .eslintrc.js
================================================
'use strict';

var OFF = 0;
var ERROR = 2;

var config = {
    extends: [],
    plugins: ['jsdoc'],
    env: {
        browser: false,
        node: true,
        es6: true
    },
    parserOptions: {
        ecmaVersion: 2018
    },
    rules: {}
};

if (!process.env.NO_LINT) {
    // possible errors
    config.rules['no-cond-assign'] = ERROR;
    config.rules['no-console'] = OFF;
    config.rules['no-constant-condition'] = ERROR;
    config.rules['no-control-regex'] = ERROR;
    config.rules['no-debugger'] = ERROR;
    config.rules['no-dupe-args'] = ERROR;
    config.rules['no-dupe-keys'] = ERROR;
    config.rules['no-duplicate-case'] = ERROR;
    config.rules['no-empty'] = ERROR;
    config.rules['no-empty-character-class'] = ERROR;
    config.rules['no-ex-assign'] = ERROR;
    config.rules['no-extra-boolean-cast'] = ERROR;
    config.rules['no-extra-semi'] = ERROR;
    config.rules['no-func-assign'] = ERROR;
    // config.rules['one-var'] = [ERROR, 'always']; // TODO: var overlapping
    // this is for variable hoisting, not necessary if we use block scoped declarations
    // config.rules['no-inner-declarations'] = [ ERROR, 'both' ];
    config.rules['no-invalid-regexp'] = ERROR;
    config.rules['no-irregular-whitespace'] = ERROR;
    config.rules['no-negated-in-lhs'] = ERROR;
    config.rules['no-reserved-keys'] = OFF;
    config.rules['no-regex-spaces'] = ERROR;
    config.rules['no-sparse-arrays'] = ERROR;
    config.rules['no-unreachable'] = ERROR;
    config.rules['use-isnan'] = ERROR;
    config.rules['valid-jsdoc'] = [
        ERROR,
        {
            requireReturnDescription: false,
            prefer: {
                return: 'returns'
            }
        }
    ];
    config.rules['valid-typeof'] = ERROR;

    // best practices
    config.rules['func-names'] = ERROR;
    config.rules['block-scoped-var'] = ERROR;
    config.rules['consistent-return'] = ERROR;
    config.rules['curly'] = OFF;
    config.rules['default-case'] = ERROR;
    config.rules['dot-notation'] = [ERROR, { allowKeywords: true }];
    config.rules['eqeqeq'] = ERROR;
    config.rules['guard-for-in'] = ERROR;
    config.rules['no-alert'] = ERROR;
    config.rules['no-caller'] = ERROR;
    config.rules['no-div-regex'] = ERROR;
    config.rules['no-eq-null'] = ERROR;
    config.rules['no-eval'] = ERROR;
    config.rules['no-extend-native'] = ERROR;
    config.rules['no-extra-bind'] = ERROR;
    config.rules['no-fallthrough'] = ERROR;
    config.rules['no-floating-decimal'] = ERROR;
    config.rules['no-implied-eval'] = ERROR;
    config.rules['no-iterator'] = ERROR;
    config.rules['no-labels'] = ERROR;
    config.rules['no-lone-blocks'] = ERROR;
    config.rules['no-loop-func'] = OFF;
    config.rules['no-multi-spaces'] = OFF;
    config.rules['no-multi-str'] = OFF;
    config.rules['no-native-reassign'] = ERROR;
    config.rules['no-new'] = OFF;
    config.rules['no-new-func'] = ERROR;
    config.rules['no-new-wrappers'] = ERROR;
    config.rules['no-octal'] = ERROR;
    config.rules['no-octal-escape'] = ERROR;
    config.rules['no-param-reassign'] = OFF;
    config.rules['no-proto'] = ERROR;
    config.rules['no-process-env'] = OFF;
    config.rules['no-redeclare'] = ERROR;
    config.rules['no-return-assign'] = ERROR;
    config.rules['no-script-url'] = ERROR;
    config.rules['no-self-compare'] = ERROR;
    config.rules['no-sequences'] = ERROR;
    config.rules['no-throw-literal'] = ERROR;
    config.rules['no-unused-expressions'] = ERROR;

    config.rules['no-warning-comments'] = [1];
    config.rules['no-with'] = ERROR;
    config.rules['radix'] = ERROR;
    config.rules['wrap-iife'] = ERROR;

    // strict mode
    config.rules['strict'] = [ERROR, 'global'];

    // variables
    config.rules['no-catch-shadow'] = ERROR;
    config.rules['no-delete-var'] = ERROR;
    config.rules['no-shadow'] = ERROR;
    config.rules['no-shadow-restricted-names'] = ERROR;
    config.rules['no-undef'] = ERROR;
    config.rules['no-undef-init'] = ERROR;
    config.rules['no-undefined'] = OFF;
    config.rules['no-unused-vars'] = [ERROR, { vars: 'all', args: 'none' }];
    config.rules['no-use-before-define'] = [ERROR, 'nofunc'];

    // node.js
    config.rules['handle-callback-err'] = [ERROR, '^.*(e|E)rr'];
    config.rules['no-mixed-requires'] = ERROR;
    config.rules['no-new-require'] = ERROR;
    config.rules['no-path-concat'] = OFF;
    config.rules['no-process-exit'] = OFF;
}

// stylistic.
if (!process.env.NO_STYLE) {
    // Global
    config.rules['max-len'] = [ERROR, { code: 80, ignoreComments: true }];

    // Prettier
    config.extends.push('prettier');
    config.plugins.push('prettier');
    config.rules['prettier/prettier'] = ERROR;

    // JSDoc
    config.rules['jsdoc/check-param-names'] = ERROR;
    config.rules['jsdoc/check-tag-names'] = ERROR;
    config.rules['jsdoc/newline-after-description'] = ERROR;
    config.rules['jsdoc/require-hyphen-before-param-description'] = ERROR;
    config.rules['jsdoc/require-param'] = ERROR;
    config.rules['jsdoc/require-param-description'] = ERROR;
    config.rules['jsdoc/require-param-type'] = ERROR;
    config.rules['jsdoc/require-returns-description'] = ERROR;
    config.rules['jsdoc/require-returns-type'] = ERROR;
}

module.exports = config;


================================================
FILE: .github/ISSUE_TEMPLATE/1-bug-report.md
================================================
---
name: "\U0001F41B Bug report"
about: Create a report to help us improve

---

<!-- Thank you for taking the time to open an issue for restify! If this is
your first time here, welcome to our community! We are a group of developers
who work on restify in our free-time. Some of us do it as a hobby, others are
using restify at work. When asking for help here, keep in mind most of us are
volunteers contributing our daily work back to the community at no cost (and
often for no reward). Please be respectful!

Below you will find two templates, one for filing a bug report, and the other
for requesting a feature. Remove the comments from around the template that is
applicable to your case and fill it out accordingly. This standardization helps
the maintainers gather the information they need up front to verify and respond
to problems accordingly, ensuring you get the fastest response possible! -->

<!-- REQUIRED: Pre-Submission Checklist -->

- [ ] Used appropriate template for the issue type
- [ ] Searched both open and closed issues for duplicates of this issue
- [ ] Title adequately and _concisely_ reflects the feature or the bug

**Restify Version**: 
**Node.js Version**: 

## Expected behaviour
<!-- This section details what you expected restify to do based on the code
that you wrote -->

## Actual behaviour
<!-- This section details what restify actually did when you ran your code -->

## Repro case
<!-- Please include a simple and concise example reproducing this bug. Please
_do not_ just dump your application here. By either not providing a repro case
or by providing an overly complicated repro case, you are offloading the work
of isolating your bug to other developers, many of which are here voluntarily.
Good repro cases are single file Node.js applications, where the only logic
present is logic necessary to expose the undesired behaviour. You will often
find that when creating your repro case, you will solve the problem yourself!
-->

## Cause
<!--
If you have been able to trace the bug back to it source(s) in the code base,
please link to them here. -->

## Are you willing and able to fix this?
<!-- "Yes" or, if "no", what can current contributors do to help you create a
PR?  If this issue is unique, as the checklist you completed above suggests,
then you are one of the few people who have encountered this bug in the wild.
While contributors will often help work on issues out of the kindness of their
hearts, its important to remember that you are the largest stakeholder in
seeing this bug resolved as you are the one experiencing it. Kindness and
contributions are what make Free Software go round, help pay it forward! -->



================================================
FILE: .github/ISSUE_TEMPLATE/2-feature-request.md
================================================
---
name: "\U0001F680 Feature request"
about: Suggest an idea for this project

---

<!-- Thank you for taking the time to open an issue for restify! If this is
your first time here, welcome to our community! We are a group of developers
who work on restify in our free-time. Some of us do it as a hobby, others are
using restify at work. When asking for help here, keep in mind most of us are
volunteers contributing our daily work back to the community at no cost (and
often for no reward). Please be respectful!

Below you will find two templates, one for filing a bug report, and the other
for requesting a feature. Remove the comments from around the template that is
applicable to your case and fill it out accordingly. This standardization helps
the maintainers gather the information they need up front to verify and respond
to problems accordingly, ensuring you get the fastest response possible! -->

<!-- REQUIRED: Pre-Submission Checklist -->

- [ ] Used appropriate template for the issue type
- [ ] Searched both open and closed issues for duplicates of this issue
- [ ] Title adequately and _concisely_ reflects the feature or the bug

# Feature Request

## Use Case
<!-- Why do you want this? -->

## Example API
<!-- This should include code snippets and documentation for the proposed
feature -->

## Are you willing and able to implement this?
<!-- "Yes" or, if "no", what can current contributors do to help you create a
PR? -->


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Thank you for taking the time to open an PR for restify! If this is your first
time here, welcome to our community! We are a group of developers who work on
restify in our free-time. Some of us do it as a hobby, others are using restify
at work. When asking for help here, keep in mind most of us are volunteers
contributing our daily work back to the community at no cost (and often for no
reward). Please be respectful!

Below you will find a checklist to help you create the best PR possible. While
the checklist items aren't all _strictly_ required, they dramatically increase
the probability of your PR getting a response and getting merged. Often times,
the least time consuming part of maintaining and open source project is writing
code, its the process and discussions that happen around the code base that
consume a majority of the maintainers' time. By spending a few moments to
adhere to this template, you are not only improve the quality of your PR, you
are also helping save the maintainers a considerable amount of time when trying
to understand and review your changes.

And remember, positive vibes are met with positive vibes. Kindness helps Free
Software go round, pay it forward!
-->

## Pre-Submission Checklist

- [ ] Opened an issue discussing these changes before opening the PR
- [ ] Ran the linter and tests via `make prepush`
- [ ] Included comprehensive and convincing tests for changes

## Issues

Closes:

* Issue #
* Issue #
* Issue #

> Summarize the issues that discussed these changes

# Changes

> What does this PR do?


================================================
FILE: .github/stale.yml
================================================
daysUntilStale: 60
daysUntilClose: 14
exemptLabels:
  - Critical
  - Serve
staleLabel: Stale
markComment: >
  This issue has been automatically marked as stale because it has not had
  recent activity. It will be closed if no further activity occurs. Thank you
  for your contributions.
closeComment: >
  This issue has been automatically closed as stale because it has not had
  recent activity.


================================================
FILE: .github/workflows/ci.yml
================================================
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
name: ci
jobs:
  lint:
    name: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: install node v16
        uses: actions/setup-node@v1
        with:
          node-version: v16.x
      - name: install dependencies
        run: npm install
      - name: check lint
        run: make check-lint
  test:
    name: test node ${{ matrix.node-version }} on ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os:
          - ubuntu-latest
        node-version:
          - 14.x
          - 16.x
          - 18.x
          - 20.x
    runs-on: ${{matrix.os}}
    steps:
      - uses: actions/checkout@v2
      - name: use node ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - name: install dependencies
        run: npm install
      - name: test
        run: make test
        env:
          TEST_SKIP_IP_V6: true


================================================
FILE: .github/workflows/release-please.yml
================================================
on:
  push:
    branches:
      - master
      - 9.x
name: release-please
jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - uses: GoogleCloudPlatform/release-please-action@v3.6.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          release-type: node
          package-name: restify


================================================
FILE: .gitignore
================================================
node_modules
docs/*.html
docs/pkg
examples/todoapp/node_modules
*.log
*.tar.gz
*.tgz
build
docs/*.json
nbproject
deps/javascriptlint
deps/jsstyle
package-lock.json
benchmark/results
.nyc_output/
coverage/
cover_html/


================================================
FILE: .npmignore
================================================
.coverage_data
.dir-locals.el
.gitmodules
.github
.travis.yml
Makefile
cover_html
deps
docs
examples
test
tools
.vscode
.idea
benchmark
.dir-locals.el
.eslintignore
.eslintrc.js
.gitignore
.prettierignore
.prettierrc
.tern-project
.travis.yml
CONTRIBUTING.md
FEATURE_REQUESTS.md
*.log
*.tar.gz
*.tgz
node_modules


================================================
FILE: .prettierignore
================================================
cover_html


================================================
FILE: .prettierrc
================================================
{
  "tabWidth": 4,
  "singleQuote": true
}


================================================
FILE: .tern-project
================================================
{
  "libs": [
     "ecma5",
     "chai"
  ],
  "plugins": {
    "node": {},
    "complete_strings": {},
    "doc_comment": {},
    "node_resolve": {}
  }
}


================================================
FILE: CHANGELOG.md
================================================
## [9.0.0](https://www.github.com/restify/node-restify/compare/v8.6.1...v9.0.0) (2022-11-15)


### ⚠ BREAKING CHANGES

* remove deprecated usage of pino.child (#1902)
* deprecates and removes re-routing when passing a string parameter to `next()`
* removes `RequestCaptureStream` and replaces `Bunyan` with `Pino`
* adds async/await support to pre, use and handler chains
* drops suppoprt to node 8 and updates linting rules
* **server:** - Server returns `RequestCloseError` instead of `RequestAbortedError`
* **travisci:** dropping support below Node.js 4

### Features

* async/await support ([12be9e2](https://www.github.com/restify/node-restify/commit/12be9e243a407eaf7a30cbb16e399ee2a46dec93))
* deprecate req.closed ([d052b7c](https://www.github.com/restify/node-restify/commit/d052b7cec561133c002211a20dccf7cc2a8a0897))
* provide callback to uncaughtException handler ([#1766](https://www.github.com/restify/node-restify/issues/1766)) ([5e8b5e2](https://www.github.com/restify/node-restify/commit/5e8b5e2b28e32c79c413d9dec2466fe8f1135332))
* remove re-routing from handler ([#1847](https://www.github.com/restify/node-restify/issues/1847)) ([9153587](https://www.github.com/restify/node-restify/commit/9153587c023a876237c1d8bc7491fee4984d9074))
* send 500s for unhandled requests ([#1777](https://www.github.com/restify/node-restify/issues/1777)) ([885cecd](https://www.github.com/restify/node-restify/commit/885cecd7f9753b62faaa930f3cd39329057587f3))
* **audit:** Add the ability to specify a custom audit log serializer (for err, req and res) ([#1746](https://www.github.com/restify/node-restify/issues/1746)) ([6231acd](https://www.github.com/restify/node-restify/commit/6231acda7e16ce64253b08039bd0ad341126c11a))
* **chain:** schedule handlers to the next tick ([#1798](https://www.github.com/restify/node-restify/issues/1798)) ([806ed71](https://www.github.com/restify/node-restify/commit/806ed7119db9ed4cce77aef3d898aae561224dd8))
* **chain:** use nextTick instead of setImmediate ([#1808](https://www.github.com/restify/node-restify/issues/1808)) ([703470a](https://www.github.com/restify/node-restify/commit/703470ad82fd01e7f3b2197ebb7eb1b5b37975f8))
* **deps:** replace cover/istanbul with nyc ([#1823](https://www.github.com/restify/node-restify/issues/1823)) ([361f83e](https://www.github.com/restify/node-restify/commit/361f83e5acd814881c82add3e1bd06ce9ded777c))
* **first:** Handlers that execute ASAP in the req/res lifecycle ([#1756](https://www.github.com/restify/node-restify/issues/1756)) ([8178098](https://www.github.com/restify/node-restify/commit/8178098d3e85ad9bd13c536b504adf940ef08563))
* **http2:** add native HTTP/2 support ([#1489](https://www.github.com/restify/node-restify/issues/1489)) ([6b20285](https://www.github.com/restify/node-restify/commit/6b202853d62394f0448486c9b5bbc18589fd44e2))
* **plugin:** plugin to serve static files ([#1753](https://www.github.com/restify/node-restify/issues/1753)) ([a67b25f](https://www.github.com/restify/node-restify/commit/a67b25f472c7ec99e63f358b3c1e8801d6261148))
* Ability to find a route by a path ([711a489](https://www.github.com/restify/node-restify/commit/711a4897800e2ef8bc4a1a9c6cc833af71cd925d))
* add router.render() back to support hypermedia usecase ([#1752](https://www.github.com/restify/node-restify/issues/1752)) ([0700cfd](https://www.github.com/restify/node-restify/commit/0700cfd445e45401c36c4229e37e12b8220339d9)), closes [#1684](https://www.github.com/restify/node-restify/issues/1684)
* **helpers:** add compose feature ([#1660](https://www.github.com/restify/node-restify/issues/1660)) ([eb60ef4](https://www.github.com/restify/node-restify/commit/eb60ef403ad77b1dd187e199d72e7c80caca248c))
* **plugins:** context, req.get() returns the whole context ([#1739](https://www.github.com/restify/node-restify/issues/1739)) ([6e35e01](https://www.github.com/restify/node-restify/commit/6e35e01eb6d64f80c0e3db2daf4dbf3f66c35e86))
* **plugins:** do not include user-input in UnsupportedMediaTypeError message (VError fails), move it to info ([#1733](https://www.github.com/restify/node-restify/issues/1733)) ([06c220d](https://www.github.com/restify/node-restify/commit/06c220d2d9629e3510aed493a8877629bbc0c4ae))
* **req:** add restifyDone event ([#1740](https://www.github.com/restify/node-restify/issues/1740)) ([4900d6b](https://www.github.com/restify/node-restify/commit/4900d6bdd51fa4e1769678562de69929c38a0c4b))
* add support for non-strict formatters ([#1721](https://www.github.com/restify/node-restify/issues/1721)) ([de1833a](https://www.github.com/restify/node-restify/commit/de1833a44084e5f231de289421518ec646b86f60))
* jsonBodyParser handles extended content types *+json ([#1663](https://www.github.com/restify/node-restify/issues/1663)) ([4537514](https://www.github.com/restify/node-restify/commit/45375144feb6a215ebfdb967ff0944e3aa21f48d))
* **router:** add ignoreTrailingSlash router option ([#1632](https://www.github.com/restify/node-restify/issues/1632)) ([92ffbf5](https://www.github.com/restify/node-restify/commit/92ffbf5cbe49df09d9c59a6081285c12fe5943b4))
* **server:** new router and middleware system ([#1561](https://www.github.com/restify/node-restify/issues/1561)) ([8283277](https://www.github.com/restify/node-restify/commit/82832771826321480e5e524db258668f62b689c2))
* cpuUsageThrottle ([#1460](https://www.github.com/restify/node-restify/issues/1460)) ([84be679](https://www.github.com/restify/node-restify/commit/84be6799c4a80ae67f3aa03165c8031a55bddc97))
* **throttle plugin:** expose rate limit metrics as headers ([#1453](https://www.github.com/restify/node-restify/issues/1453)) ([1627a55](https://www.github.com/restify/node-restify/commit/1627a557bd4ed94ba1c6adbe916c51f83bc46059))
* create inflightRequestThrottle plugin ([#1431](https://www.github.com/restify/node-restify/issues/1431)) ([285faf4](https://www.github.com/restify/node-restify/commit/285faf4b6a2e56f0e4d9fc6dfaa3dd5e311530c1))
* revert async formatters ([#1377](https://www.github.com/restify/node-restify/issues/1377)) ([a2e300f](https://www.github.com/restify/node-restify/commit/a2e300f785edb087da9a52f562bd1f900e9ab47a))


### Bug Fixes

* add support for secureOptions in createServer ([#1575](https://www.github.com/restify/node-restify/issues/1575)) ([656e60e](https://www.github.com/restify/node-restify/commit/656e60e03d5fe2b011f8b2198178bc22d749b21f))
* Allow multiple unmerged set-cookie headers. ([#1570](https://www.github.com/restify/node-restify/issues/1570)) ([df04015](https://www.github.com/restify/node-restify/commit/df04015439becae8e8c48a02cb6e1992d6040037))
* Correct typo in assertion message ([#1904](https://www.github.com/restify/node-restify/issues/1904)) ([195cf13](https://www.github.com/restify/node-restify/commit/195cf136e3a7de2b2720261dfd459c051b5be037))
* documentation typo fix ([#1688](https://www.github.com/restify/node-restify/issues/1688)) ([0fa7132](https://www.github.com/restify/node-restify/commit/0fa71328b8f01f301b0e729f5ef0f00d1b203231))
* don't create empty clientError listener for http.Server ([#1895](https://www.github.com/restify/node-restify/issues/1895)) ([ddc1042](https://www.github.com/restify/node-restify/commit/ddc1042af427fe6383ebea37201c06b7b424e72f))
* emit after event with proper error param for node versions >= 11.4.0 ([#1732](https://www.github.com/restify/node-restify/issues/1732)) ([7a1378b](https://www.github.com/restify/node-restify/commit/7a1378b0353e9b3f1b630e4cab489c8c578000f5))
* examples/todoapp/package.json to reduce vulnerabilities ([#1832](https://www.github.com/restify/node-restify/issues/1832)) ([d9b27c6](https://www.github.com/restify/node-restify/commit/d9b27c602e260fc6c4f0e18e8b6835e89fa2adca))
* format falsy constants properly in json formatter ([#1792](https://www.github.com/restify/node-restify/issues/1792)) ([3002182](https://www.github.com/restify/node-restify/commit/3002182cacc7a9334237a9284a339ba93d3f213c))
* make arity error message actionable ([#1901](https://www.github.com/restify/node-restify/issues/1901)) ([97b6f93](https://www.github.com/restify/node-restify/commit/97b6f936e43860873f847bdd752b8090b3119da0))
* more flaky metrics.test.js fixes ([#1730](https://www.github.com/restify/node-restify/issues/1730)) ([71aac42](https://www.github.com/restify/node-restify/commit/71aac4283a1ae4ebd3c290afb83487b67010666f))
* properly handle non-errors thrown in domains ([#1757](https://www.github.com/restify/node-restify/issues/1757)) ([cb2e717](https://www.github.com/restify/node-restify/commit/cb2e7177c8b735987aed1c0839747f9658c19bb0))
* proxy events into instance var and add test script ([#1661](https://www.github.com/restify/node-restify/issues/1661)) ([de72f49](https://www.github.com/restify/node-restify/commit/de72f49eade48cc14dd916916ea86f88d46d3c8a))
* Re-add support for clientError listeners ([#1897](https://www.github.com/restify/node-restify/issues/1897)) ([05f12a6](https://www.github.com/restify/node-restify/commit/05f12a6864f4fa9aea617a42ae2d5c890478d2df))
* remove invalid triggering of uncaughtException handler ([#1710](https://www.github.com/restify/node-restify/issues/1710)) ([ee69806](https://www.github.com/restify/node-restify/commit/ee69806a338add1ebfef7eaad92a13273826c98e))
* Return 444 status code for closed and aborted requests ([#1579](https://www.github.com/restify/node-restify/issues/1579)) ([644c198](https://www.github.com/restify/node-restify/commit/644c1980aa1a21b0c7fa9aa41e22df9af6eab31e))
* send numbers or bools as payloads ([#1609](https://www.github.com/restify/node-restify/issues/1609)) ([0919f26](https://www.github.com/restify/node-restify/commit/0919f26db5d5614c0b2fa2567ac2ed43ee70b6d5))
* server should fire not acceptable event ([#1627](https://www.github.com/restify/node-restify/issues/1627)) ([8b11b71](https://www.github.com/restify/node-restify/commit/8b11b71b487d0001c96312519298f7f85b196471))
* use close event on response instead of socket ([#1892](https://www.github.com/restify/node-restify/issues/1892)) ([5c7eb95](https://www.github.com/restify/node-restify/commit/5c7eb95319aa54ef3b4b60d000d434824a666e18))
* use more reliable close event ([36318ae](https://www.github.com/restify/node-restify/commit/36318ae4c1fee02d3bc3737e34e1ea33e604f674))
* **benchmark:** force latest restify version ([#1810](https://www.github.com/restify/node-restify/issues/1810)) ([b8ec60e](https://www.github.com/restify/node-restify/commit/b8ec60e335b3ce95be4f2507623d357f4a600331))
* **bodyReader:** Fix memory leak ([#1566](https://www.github.com/restify/node-restify/issues/1566)) ([756b3f0](https://www.github.com/restify/node-restify/commit/756b3f02ba1dec114cf76c4e723ed054170a081c))
* **cpuUsageThrottle:** Always queue a new timeout ([#1484](https://www.github.com/restify/node-restify/issues/1484)) ([e4ffe43](https://www.github.com/restify/node-restify/commit/e4ffe430b47a2b51fe5fbef00dfa8bd3a1fb66c1))
* **cpuUsageThrottle:** Correctly named handler for debugInfo ([#1499](https://www.github.com/restify/node-restify/issues/1499)) ([78b0900](https://www.github.com/restify/node-restify/commit/78b0900b0ffcefa86e541c850d27779c5f656f00))
* **cpuUsageThrottle:** dont include interval in lag ([#1504](https://www.github.com/restify/node-restify/issues/1504)) ([eecb2d2](https://www.github.com/restify/node-restify/commit/eecb2d259deda34c2f297f2ef8b6d4fedc504e9e))
* **cpuUsageThrottle:** support breaking change in pidusage module ([7460064](https://www.github.com/restify/node-restify/commit/7460064fc13e5b977a295a2c939e050129c47797))
* **dev:** pin to exact versions of linting tools and fix lint errors ([3740a6b](https://www.github.com/restify/node-restify/commit/3740a6b7bf6e3bd589d9c1bc0c3d690978270564))
* **dev:** remove nsp since the project merged with npm ([1dc34b4](https://www.github.com/restify/node-restify/commit/1dc34b48de361960d7fa37d8bbc82b9d4a612981))
* **dev:** upgrading modules including restify-errors ([#1755](https://www.github.com/restify/node-restify/issues/1755)) ([3b71229](https://www.github.com/restify/node-restify/commit/3b712298c16577394d16b149be6c9a99044332b2))
* **dtrace:** route probes ([#1659](https://www.github.com/restify/node-restify/issues/1659)) ([84bcded](https://www.github.com/restify/node-restify/commit/84bcded77e9a42d3762146802418a1ae1ece8c30))
* **inflightRequestThrottle:** properly handle next ([#1471](https://www.github.com/restify/node-restify/issues/1471)) ([4db404f](https://www.github.com/restify/node-restify/commit/4db404f979d0da9651c00b076ceefb7b98a4e71f))
* **jsonBodyParser:** fix percent sign causing server fail ([#1411](https://www.github.com/restify/node-restify/issues/1411)) ([bde8fda](https://www.github.com/restify/node-restify/commit/bde8fda646a6f69b57fd72af1f00d6153fe056ec))
* **npm:** exclude extraneous files ([#1818](https://www.github.com/restify/node-restify/issues/1818)) ([e8516c3](https://www.github.com/restify/node-restify/commit/e8516c3735487ad5ebd332bc781404654c8c3cec))
* **npm:** remove unleash dependency ([#1522](https://www.github.com/restify/node-restify/issues/1522)) ([a43aa60](https://www.github.com/restify/node-restify/commit/a43aa60f090d29b8e66a58a9656126cb37bf2ef9))
* **package-lock.json:** remove artifacts.netflix.com repo ([#1526](https://www.github.com/restify/node-restify/issues/1526)) ([3d2f0f7](https://www.github.com/restify/node-restify/commit/3d2f0f7d0ddc14238691944cb9a1a60b02ae5947))
* **plugins:** save req._matchedVersion ([#1642](https://www.github.com/restify/node-restify/issues/1642)) ([69f917a](https://www.github.com/restify/node-restify/commit/69f917a3db66fac58f01c9e16535c2e2fcf2172b))
* **plugins:** use process.hrtime() for duration calculation ([#1507](https://www.github.com/restify/node-restify/issues/1507)) ([e8efd6c](https://www.github.com/restify/node-restify/commit/e8efd6cdcb73e674583e2a7081d2a9b923c72809))
* **request:** date() and time() methods return value ([#1576](https://www.github.com/restify/node-restify/issues/1576)) ([4c2cb1a](https://www.github.com/restify/node-restify/commit/4c2cb1a7edfe6252e68e409d850aef73961338ca))
* **server:** address domain performance regression with Node v12.x ([#1809](https://www.github.com/restify/node-restify/issues/1809)) ([e648d49](https://www.github.com/restify/node-restify/commit/e648d491151484f17263c6774678f1e7ac2fa188))
* **server:** address req and res close event changes in Node v10.x ([#1672](https://www.github.com/restify/node-restify/issues/1672)) ([6be3fb7](https://www.github.com/restify/node-restify/commit/6be3fb7c07483ee1991eba9aaa9ad4897c5a4965))
* **server:** avoid http2 experimental warning without http2 option ([#1555](https://www.github.com/restify/node-restify/issues/1555)) ([12da7fd](https://www.github.com/restify/node-restify/commit/12da7fdfc68dd9467da97ae0b2f45b89cb540b9b))
* **server:** avoiding uncaughtException in _routeErrorResponse by only sending response when not sent ([#1568](https://www.github.com/restify/node-restify/issues/1568)) ([cf65c65](https://www.github.com/restify/node-restify/commit/cf65c65cabd06bd5d17d84cd28999248dada94f7))
* **server:** fix uncaught exceptions triggering route lookups ([#1717](https://www.github.com/restify/node-restify/issues/1717)) ([e49cb3b](https://www.github.com/restify/node-restify/commit/e49cb3b24c3f4d77fa0b3204f3c1a618fb054789))
* **test:** make upgrade test pass ([#1772](https://www.github.com/restify/node-restify/issues/1772)) ([d30b748](https://www.github.com/restify/node-restify/commit/d30b7483c4d035e9a3fa94114557ae9d5f058f79))
* 652 - Incorrect error on route with no versions ([#1465](https://www.github.com/restify/node-restify/issues/1465)) ([ee15490](https://www.github.com/restify/node-restify/commit/ee154908d3ec4fd4a4108019140820c172df66b5))
* Add migration guid to website ([#1402](https://www.github.com/restify/node-restify/issues/1402)) ([5f053c7](https://www.github.com/restify/node-restify/commit/5f053c7efebc414b5a26daac3cc5e89dc0054fe3))
* add node 7-8 travis support ([#1405](https://www.github.com/restify/node-restify/issues/1405)) ([536a473](https://www.github.com/restify/node-restify/commit/536a4735266a7f56c205be4c6cafaa6adf81f480))
* create unit tests for sanitizePath plugin ([#1352](https://www.github.com/restify/node-restify/issues/1352)) ([12714cf](https://www.github.com/restify/node-restify/commit/12714cfce5048c65b4256df660766e863578b90a))
* doc site ([#1393](https://www.github.com/restify/node-restify/issues/1393)) ([76ee548](https://www.github.com/restify/node-restify/commit/76ee5480cfcb7f36e39e3e0955102c04abdac867))
* documentation update for restifyError event example ([#1398](https://www.github.com/restify/node-restify/issues/1398)) ([94fe715](https://www.github.com/restify/node-restify/commit/94fe715173ffcebd8814bed7e17a22a24fac4ae8))
* emit restifyError event even for router errors ([#1420](https://www.github.com/restify/node-restify/issues/1420)) ([f9d02d5](https://www.github.com/restify/node-restify/commit/f9d02d5b358863b9e067da5d6c89b4e283f420ba))
* redirect should work even when hostname or protocol is not specified in req.url ([#1497](https://www.github.com/restify/node-restify/issues/1497)) ([e696a1f](https://www.github.com/restify/node-restify/commit/e696a1f80cd84e7d3db9fb85a18212f970f9a0d3))
* **server:** error in pre handler triggers after event ([#1500](https://www.github.com/restify/node-restify/issues/1500)) ([c2e6dea](https://www.github.com/restify/node-restify/commit/c2e6deae5dab78187a8b09ce5256fb09db390bc9))
* exclude package-lock.json ([#1477](https://www.github.com/restify/node-restify/issues/1477)) ([011fdf0](https://www.github.com/restify/node-restify/commit/011fdf0e2e5b456fe18c9d2ef838819f52586c14))
* **static:** avoid user-provided data in Error messages being interpreted as sprintf codes ([#1384](https://www.github.com/restify/node-restify/issues/1384)) ([#1472](https://www.github.com/restify/node-restify/issues/1472)) ([9906344](https://www.github.com/restify/node-restify/commit/99063447419e7dcd0bf4ff6c38c5ad1867a2e1f3))
* audit timers of same name should accumulate ([#1435](https://www.github.com/restify/node-restify/issues/1435)) ([#1443](https://www.github.com/restify/node-restify/issues/1443)) ([a2d34aa](https://www.github.com/restify/node-restify/commit/a2d34aaa461cabf47147990a1c2910ea9a53b2d8))
* GH-1438, error reponse customization documentation incorrect ([#1439](https://www.github.com/restify/node-restify/issues/1439)) ([dd66088](https://www.github.com/restify/node-restify/commit/dd66088f3067d4b0858a2dd0274c705faf374e0e))
* Honor port for redirect ([#1363](https://www.github.com/restify/node-restify/issues/1363)) ([61c0cb5](https://www.github.com/restify/node-restify/commit/61c0cb5c697bcd84c2f7255bfe158619694fb73d))
* monkey patch getHeaders for pre-v7 Node.js (GH-1409) ([82088a7](https://www.github.com/restify/node-restify/commit/82088a7185331c7de092450ffec52d815c079739))
* package.json version now matches npm ([9944dbd](https://www.github.com/restify/node-restify/commit/9944dbd57795fa312c8f35c4734977698d70c895))
* respect when status code is set with res.status (GH-1429) ([#1440](https://www.github.com/restify/node-restify/issues/1440)) ([5abc067](https://www.github.com/restify/node-restify/commit/5abc06779df3b3ed4faf4d19f0815051a7c3106b))
* test static plugin's handling of sprintf escape sequences ([#1391](https://www.github.com/restify/node-restify/issues/1391)) ([5d7039a](https://www.github.com/restify/node-restify/commit/5d7039a5b97e158347fbb918b866b7aeebd4a14f))
* update chai (^3.4.1 to ^4.0.0) ([f982d0c](https://www.github.com/restify/node-restify/commit/f982d0c71f1b72f79e07f33f6cdf43741242f5d8))
* Update dependency mime to 1.4.0 ([#1467](https://www.github.com/restify/node-restify/issues/1467)) ([6d38b38](https://www.github.com/restify/node-restify/commit/6d38b38c7a67e9b7cb8500fd1a92751e5ea4ee38))
* update http-signature to v1.0.0 ([#1401](https://www.github.com/restify/node-restify/issues/1401)) ([ec88737](https://www.github.com/restify/node-restify/commit/ec887376a8314edbb623db48e6288d5a352a4efd))
* use `Buffer.isBuffer` instead of `util.isBuffer`. ([#1593](https://www.github.com/restify/node-restify/issues/1593)) ([35bd1c2](https://www.github.com/restify/node-restify/commit/35bd1c2b375ea70dc2b4a4549461ff59ff5e4ec4))
* versioned route matching should not throw TypeError ([#1381](https://www.github.com/restify/node-restify/issues/1381)) ([25d10f0](https://www.github.com/restify/node-restify/commit/25d10f00a4c9128b87cda0261aa3a041ac652f63))
* **audit:** use public APIs for accessing response headers ([5169db7](https://www.github.com/restify/node-restify/commit/5169db7b1d2c9979e534b2c27912f5be398bcbca)), closes [/nodejs.org/api/deprecations.html#deprecations_dep0066](https://www.github.com/restify//nodejs.org/api/deprecations.html/issues/deprecations_dep0066)


* Prefer Pino logger over Bunyan (#1841) ([2f5bf87](https://www.github.com/restify/node-restify/commit/2f5bf8722c9e0ba0d45f32af5c2c16ddbaa538b4)), closes [#1841](https://www.github.com/restify/node-restify/issues/1841)


### Miscellaneous Chores

* drop support for node 8 ([bd34988](https://www.github.com/restify/node-restify/commit/bd349884321d3e8af549f4d9da4456774e82ac8b))
* remove deprecated usage of pino.child ([#1902](https://www.github.com/restify/node-restify/issues/1902)) ([0a8cf83](https://www.github.com/restify/node-restify/commit/0a8cf8345de26f8ee98e87c0085f0f9439302d98))
* **travisci:** revisit nodejs version. Change to: LTS active, LTS maintenance (4.x) and stable releases ([#1553](https://www.github.com/restify/node-restify/issues/1553)) ([49eb008](https://www.github.com/restify/node-restify/commit/49eb008d987f1c425989b78e2336e3583e05a88a))

## [11.2.0](https://github.com/restify/node-restify/compare/v11.1.0...v11.2.0) (2023-08-11)


### Features

* allow alternate name for request id in logs ([cbd16ef](https://github.com/restify/node-restify/commit/cbd16efa3be36e7888ecccc15ee28eaa8fa6c5ef))
* support Node.js 20 ([9f1d249](https://github.com/restify/node-restify/commit/9f1d249c3fd023b05ac15c02352ec937ff7d1299))


### Bug Fixes

* tests broke due to find-my-way update ([f8beaae](https://github.com/restify/node-restify/commit/f8beaaef64c0541185bc4c2d864948d3c1299cc9))

## [11.1.0](https://github.com/restify/node-restify/compare/v11.0.0...v11.1.0) (2023-02-24)


### Features

* allow custom alternatives to domains ([54adfcb](https://github.com/restify/node-restify/commit/54adfcbdea1a6be3675dbc05573f8063fc16a05b))

## [11.0.0](https://github.com/restify/node-restify/compare/v10.0.0...v11.0.0) (2023-01-17)


### ⚠ BREAKING CHANGES

* don't override req.log if set during .first
* use req.log on audit plugin

### Features

* don't override req.log if set during .first ([852d2c1](https://github.com/restify/node-restify/commit/852d2c153d1815274db8cdd7799625e9740090b3))
* use req.log on audit plugin ([528ecbc](https://github.com/restify/node-restify/commit/528ecbcec5d70c458749bdd4c4cc3f9e06ab69a2))

## [10.0.0](https://github.com/restify/node-restify/compare/v9.0.0...v10.0.0) (2022-11-29)


### ⚠ BREAKING CHANGES

* support v18.x

### Features

* bump dtrace-provider version to avoid MacOS errors ([fa52f60](https://github.com/restify/node-restify/commit/fa52f60d85c3df8a1babde98be184bb918958ef3))
* support v18.x ([5795223](https://github.com/restify/node-restify/commit/57952239fa1808a6cf6e70deb2754c4c85c1be39))

### 8.5.1 (2019-12-13)


#### Bug Fixes

* **benchmark:** force latest restify version (#1810) ([b8ec60e3](git://github.com/restify/node-restify.git/commit/b8ec60e3))
* **server:** address domain performance regression with Node v12.x (#1809) ([e648d491](git://github.com/restify/node-restify.git/commit/e648d491))


<a name="8.5.0"></a>
## 8.5.0 (2019-12-02)


#### Features

* **chain:** use nextTick instead of setImmediate (#1808) ([703470ad](git://github.com/restify/node-restify.git/commit/703470ad))


<a name="8.4.1"></a>
### 8.4.1 (2019-11-27)


<a name="8.4.0"></a>
## 8.4.0 (2019-07-31)


#### Features

* **chain:** schedule handlers to the next tick (#1798) ([806ed711](git://github.com/restify/node-restify.git/commit/806ed711))


<a name="8.3.3"></a>
### 8.3.3 (2019-06-04)


<a name="8.3.2"></a>
### 8.3.2 (2019-05-06)


<a name="8.3.1"></a>
### 8.3.1 (2019-04-25)


#### Bug Fixes

* **test:** make upgrade test pass (#1772) ([d30b7483](git://github.com/restify/node-restify.git/commit/d30b7483))


<a name="8.3.0"></a>
## 8.3.0 (2019-04-11)


#### Features

* provide callback to uncaughtException handler (#1766) ([5e8b5e2b](git://github.com/restify/node-restify.git/commit/5e8b5e2b))


<a name="8.2.0"></a>
## 8.2.0 (2019-03-18)


#### Bug Fixes

* properly handle non-errors thrown in domains (#1757) ([cb2e7177](git://github.com/restify/node-restify.git/commit/cb2e7177))
* **cpuUsageThrottle:** support breaking change in pidusage module ([7460064f](git://github.com/restify/node-restify.git/commit/7460064f))


#### Features

* **first:** Handlers that execute ASAP in the req/res lifecycle (#1756) ([8178098d](git://github.com/restify/node-restify.git/commit/8178098d))


<a name="8.1.1"></a>
### 8.1.1 (2019-03-14)

#### Bug Fixes

* Published NPM package had a bad dependency on `npm` causing new irrelevant packages to get installed

<a name="8.1.0"></a>
## 8.1.0 (2019-03-06)


#### Bug Fixes

* **dev:** upgrading modules including restify-errors (#1755) ([3b712298](git://github.com/restify/node-restify.git/commit/3b712298))


#### Features

* add router.render() back to support hypermedia usecase (#1752) ([0700cfd4](git://github.com/restify/node-restify.git/commit/0700cfd4), closes [#1684](git://github.com/restify/node-restify.git/issues/1684))
* **plugin:** plugin to serve static files (#1753) ([a67b25f4](git://github.com/restify/node-restify.git/commit/a67b25f4))


<a name="8.0.0"></a>
## 8.0.0 (2019-02-20)
#### Breaking Changes

* Dropped Support for Node v4.x and Node v6.x


<a name="7.7.0"></a>
## 7.7.0 (2019-02-01)


#### Bug Fixes

* **dev:**
  * remove nsp since the project merged with npm ([1dc34b48](git://github.com/restify/node-restify.git/commit/1dc34b48))
  * pin to exact versions of linting tools and fix lint errors ([3740a6b7](git://github.com/restify/node-restify.git/commit/3740a6b7))


#### Features

* **audit:** Add the ability to specify a custom audit log serializer (for err, req and res)  ([6231acda](git://github.com/restify/node-restify.git/commit/6231acda))


<a name="7.6.0"></a>
## 7.6.0 (2019-01-18)


#### Features

* **req:** add restifyDone event (#1740) ([4900d6bd](git://github.com/restify/node-restify.git/commit/4900d6bd))


<a name="7.5.0"></a>
## 7.5.0 (2019-01-09)


#### Bug Fixes

* emit after event with proper error param for node versions >= 11.4.0 (#1732) ([7a1378b0](git://github.com/restify/node-restify.git/commit/7a1378b0))


#### Features

* **plugins:** context, req.get() returns the whole context (#1739) ([6e35e01e](git://github.com/restify/node-restify.git/commit/6e35e01e))


<a name="7.4.0"></a>
## 7.4.0 (2019-01-02)


#### Bug Fixes

* more flaky metrics.test.js fixes (#1730) ([71aac428](git://github.com/restify/node-restify.git/commit/71aac428))


#### Features

* **plugins:** do not include user-input in UnsupportedMediaTypeError message (VError fails), m ([06c220d2](git://github.com/restify/node-restify.git/commit/06c220d2))


<a name="7.3.0"></a>
## 7.3.0 (2018-12-07)


#### Features

* add support for non-strict formatters (#1721) ([de1833a4](git://github.com/restify/node-restify.git/commit/de1833a4))


<a name="7.2.3"></a>
### 7.2.3 (2018-11-16)


#### Bug Fixes

* **server:** fix uncaught exceptions triggering route lookups (#1717) ([e49cb3b2](git://github.com/restify/node-restify.git/commit/e49cb3b2))


<a name="7.2.2"></a>
### 7.2.2 (2018-10-29)


#### Bug Fixes

* documentation typo fix (#1688) ([0fa71328](git://github.com/restify/node-restify.git/commit/0fa71328))


<a name="7.2.1"></a>
### 7.2.1 (2018-06-07)


#### Bug Fixes

* proxy events into instance var and add test script (#1661) ([de72f49e](git://github.com/restify/node-restify.git/commit/de72f49e))
* **server:** address req and res close event changes in Node v10.x (#1672) ([6be3fb7c](git://github.com/restify/node-restify.git/commit/6be3fb7c))


#### Features

* jsonBodyParser handles extended content types *+json (#1663) ([45375144](git://github.com/restify/node-restify.git/commit/45375144))


<a name="7.2.0"></a>
## 7.2.0 (2018-05-16)


#### Features

* **helpers:** add compose feature (#1660) ([eb60ef40](git://github.com/restify/node-restify.git/commit/eb60ef40))


<a name="7.1.2"></a>
### 7.1.2 (2018-05-15)


#### Bug Fixes

* **dtrace:** route probes (#1659) ([84bcded7](git://github.com/restify/node-restify.git/commit/84bcded7))


<a name="7.1.1"></a>
### 7.1.1 (2018-04-10)


#### Bug Fixes

* **plugins:** save req._matchedVersion (#1642) ([69f917a3](git://github.com/restify/node-restify.git/commit/69f917a3))


<a name="7.1.0"></a>
## 7.1.0 (2018-03-26)


#### Features

* **router:** add ignoreTrailingSlash router option (#1632) ([92ffbf5c](git://github.com/restify/node-restify.git/commit/92ffbf5c))


<a name="7.0.0"></a>
## 7.0.0 (2018-03-20)


#### Features

* **server:** new router and middleware system (#1561) ([1161370b](git://github.com/restify/node-restify.git/commit/1161370b))


#### Breaking Changes

*
- Server returns `RequestCloseError` instead of `RequestAbortedError`
- Non-strict routing is gone
- Different `RegExp` usage in router path and wildcards
- Remove already deprecated `next.ifError`
- Disable DTrace probes by default
- Change in calling `next` multiple times
- Router versioning and content type as a separate plugin: `conditionalHandler`
- After event fires when both request is flushed and the last handler is finished
- Metrics plugin latency logic changes and new latencies were added

For more info see the `/guides/6to7guide.md`.
 ([1161370b](git://github.com/restify/node-restify.git/commit/1161370b))
* dropping support below Node.js 4
 ([0698f45c](git://github.com/restify/node-restify.git/commit/0698f45c))


<a name="6.4.0"></a>
## 6.4.0 (2018-03-20)


#### Bug Fixes

* server should fire not acceptable event (#1627) ([8b11b71b](git://github.com/restify/node-restify.git/commit/8b11b71b))
* send numbers or bools as payloads (#1609) ([0919f26d](git://github.com/restify/node-restify.git/commit/0919f26d))
* Allow multiple unmerged set-cookie headers. (#1570) ([df040154](git://github.com/restify/node-restify.git/commit/df040154))
* add support for secureOptions in createServer (#1575) ([656e60e0](git://github.com/restify/node-restify.git/commit/656e60e0))
* use `Buffer.isBuffer` instead of `util.isBuffer`. (#1593) ([35bd1c2b](git://github.com/restify/node-restify.git/commit/35bd1c2b))
* **jsonBodyParser:** fix percent sign causing server fail (#1411) ([bde8fda6](git://github.com/restify/node-restify.git/commit/bde8fda6))
* **request:** date() and time() methods return value (#1576) ([4c2cb1a7](git://github.com/restify/node-restify.git/commit/4c2cb1a7))


<a name="6.3.4"></a>
### 6.3.4 (2017-11-21)


#### Bug Fixes

* **bodyReader:** Fix memory leak (#1566) ([756b3f02](git://github.com/restify/node-restify.git/commit/756b3f02))
* **server:** avoiding uncaughtException in _routeErrorResponse by only sending response when  ([cf65c65c](git://github.com/restify/node-restify.git/commit/cf65c65c))


<a name="6.3.2"></a>
### 6.3.2 (2017-11-08)


<a name="6.3.1"></a>
### 6.3.1 (2017-11-03)


#### Bug Fixes

* **server:** avoid http2 experimental warning without http2 option (#1555) ([12da7fdf](git://github.com/restify/node-restify.git/commit/12da7fdf))


<a name="6.3.0"></a>
## 6.3.0 (2017-11-02)


#### Features

* **http2:** add native HTTP/2 support (#1489) ([6b202853](git://github.com/restify/node-restify.git/commit/6b202853))


<a name="6.2.3"></a>
### 6.2.3 (2017-10-18)


<a name="6.2.2"></a>
### 6.2.2 (2017-10-18)


#### Bug Fixes

* **package-lock.json:** remove artifacts.netflix.com repo (#1526) ([3d2f0f7d](git://github.com/restify/node-restify.git/commit/3d2f0f7d))


<a name="6.2.1"></a>
### 6.2.1 (2017-10-18)


#### Bug Fixes

* **cpuUsageThrottle:** dont include interval in lag (#1504) ([eecb2d25](git://github.com/restify/node-restify.git/commit/eecb2d25))
* **npm:** remove unleash dependency (#1522) ([a43aa60f](git://github.com/restify/node-restify.git/commit/a43aa60f))
* **plugins:** use process.hrtime() for duration calculation (#1507) ([e8efd6cd](git://github.com/restify/node-restify.git/commit/e8efd6cd))


<a name="6.2.0"></a>
## 6.2.0 (2017-10-16)


#### Bug Fixes

* **cpuUsageThrottle:** dont include interval in lag (#1504) ([eecb2d25](git://github.com/restify/node-restify.git/commit/eecb2d25))
* **plugins:** use process.hrtime() for duration calculation (#1507) ([e8efd6cd](git://github.com/restify/node-restify.git/commit/e8efd6cd))


<a name="6.1.0"></a>
## 6.1.0 (2017-10-16)


#### Bug Fixes

* **cpuUsageThrottle:** dont include interval in lag (#1504) ([eecb2d25](git://github.com/restify/node-restify.git/commit/eecb2d25))
* **plugins:** use process.hrtime() for duration calculation (#1507) ([e8efd6cd](git://github.com/restify/node-restify.git/commit/e8efd6cd))


<a name="6.0.1"></a>
### 6.0.1 (2017-09-19)


#### Bug Fixes

* **cpuUsageThrottle:** Correctly named handler for debugInfo (#1499) ([78b0900b](git://github.com/restify/node-restify.git/commit/78b0900b))
* **server:** error in pre handler triggers after event (#1500) ([c2e6deae](git://github.com/restify/node-restify.git/commit/c2e6deae))


<a name="6.0.0"></a>
## 6.0.0 (2017-09-15)


#### Bug Fixes

* exclude package-lock.json (#1477) ([011fdf0e](git://github.com/restify/node-restify.git/commit/011fdf0e))
* Update dependency mime to 1.4.0 (#1467) ([6d38b38c](git://github.com/restify/node-restify.git/commit/6d38b38c))
* **cpuUsageThrottle:** Always queue a new timeout (#1484) ([e4ffe430](git://github.com/restify/node-restify.git/commit/e4ffe430))
* **inflightRequestThrottle:** properly handle next (#1471) ([4db404f9](git://github.com/restify/node-restify.git/commit/4db404f9))
* **static:** avoid user-provided data in Error messages being interpreted as sprintf codes (# ([99063447](git://github.com/restify/node-restify.git/commit/99063447))


#### Features

* cpuUsageThrottle (#1460) ([84be6799](git://github.com/restify/node-restify.git/commit/84be6799))
* **throttle plugin:** expose rate limit metrics as headers (#1453) ([1627a557](git://github.com/restify/node-restify.git/commit/1627a557))


<a name="5.2.0"></a>
## 5.2.0 (2017-08-16)


#### Bug Fixes

* package.json version now matches npm ([9944dbd5](git://github.com/restify/node-restify.git/commit/9944dbd5))
* create unit tests for sanitizePath plugin (#1352) ([12714cfc](git://github.com/restify/node-restify.git/commit/12714cfc))
* audit timers of same name should accumulate (#1435) (#1443) ([a2d34aaa](git://github.com/restify/node-restify.git/commit/a2d34aaa))
* respect when status code is set with res.status (GH-1429) (#1440) ([5abc0677](git://github.com/restify/node-restify.git/commit/5abc0677))
* versioned route matching should not throw TypeError (#1381) ([25d10f00](git://github.com/restify/node-restify.git/commit/25d10f00))


<a name="5.0.1"></a>
### 5.0.1 (2017-07-17)


#### Bug Fixes

* monkey patch getHeaders for pre-v7 Node.js (GH-1409) ([82088a71](git://github.com/restify/node-restify.git/commit/82088a71))
* add node 7-8 travis support (#1405) ([536a4735](git://github.com/restify/node-restify.git/commit/536a4735))
* Add migration guid to website (#1402) ([5f053c7e](git://github.com/restify/node-restify.git/commit/5f053c7e))
* update http-signature to v1.0.0 (#1401) ([ec887376](git://github.com/restify/node-restify.git/commit/ec887376))
* documentation update for restifyError event example (#1398) ([94fe7151](git://github.com/restify/node-restify.git/commit/94fe7151))
* doc site (#1393) ([76ee5480](git://github.com/restify/node-restify.git/commit/76ee5480))
* test static plugin's handling of sprintf escape sequences (#1391) ([5d7039a5](git://github.com/restify/node-restify.git/commit/5d7039a5))


================================================
FILE: CHANGES.md
================================================
# restify Changelog

## 5.0.0
 - #1377 Remove async formatters
 - #1363 Honor port for `Response.prototype.redirect`
 - #1369 Use public APIs for accessing response headers
 - #1353 Deprecate `next.ifError`
 - #1346 Return plugins to repo
 - #1322 Remove duplicate `close` event from `Server`
 - #1309 Add `getRoute()` to Request to get the route object. Rajat Kumar
 - #1288 add `pre` and `routed` events. Yunong Xiao
 - #1281 Add `server.getDebugInfo()` method, Yunong Xiao, Alex Liu
 - #1281 `server.unfinishedRequests()` to `server.inflightRequests()`, Yunong Xiao
 - #1256 add `req.id()` method, Alex Liu
 - #1251 add `req.connectionState()` method, Alex Liu
 - #1250 add `server.unfinishedRequests()` method, Alex Liu
 - #1247 Update jyoent cloud API link in README, Devinsuit
 - #1246 Fix syntax error in plugins.md example, Aria Stewart
 - #1241 Rev formidable to remove Node6+ warnings, Alex Liu
 - #1234 Update uuid to version 3.0.0, Marc Bachmann
 - #1212 Fix typos in plugins.md, Greg Walden
 - #1199 Update examples to use ES6, Amila Welihinda
 - #1190 Fix minor typo, The-Alchemist
 - #1179 Fix typo in comment, Niklas Ingholt
 - Fix dtrace demo to not use async formatter, Yunong Xiao
 - #1171 Router unmount now works for versioned routes, gcssabbagh
 - #1143 add docs about serveStatic plugin, Michael Burguet
 - #1135 ability to find a route by a path, Jacob Quatier
 - #1129 always invoke res.send callback if one is provided, even when the
   selected formatter is sync, Alex Liu
 - #1128 don't send domain errors to the client, Alex Liu
 - #1123 add deprecation warnings for domain dependent features, Alex Liu
 - #1119 set response status code to 0 when the request is terminated by the
   client, Alex Liu
 - #1118 remove undocumented exports and other unused methods, Alex Liu
 - #1113 Fix JSDOC comments, Marc Riegel
 - #1111 new documentation guides, Nicolas Artman
 - #1092 support for strict routing, lukealbao
 - #1089 remove route from LRU cache on when calling `server.rm`, Luis Gómez
 - #1086 support re-using request id headers on incoming requests, Alex Liu
 - #1081 update documentation, default content-type is now application/json,
   Dmitry Kirilyuk
 - #1078 send the server name down in the header per documentation, Alex Liu
 - #1072 update documentation for accept-version header, Ingo Renner
 - #1071 rev node-uuid to address advisory CVE-2015-8851, Alex Liu
 - #1056 fix `req.absoluteUri()` to use correct protocol, David Marek
 - #1032 fix potential xss vector, Alex Liu
 - #1024 **BREAKING** Disabled the uncaughtException handler by default, added
   server option 'handleUncaughtExceptions' to allow enabling of it again
   (restify 4.x and before used to handle exceptions by default), Todd Whiteman
 - #1047 update documentation for spdy example, Tyler Akins
 - #1041 add `rejectUnknown` option to restify plugin documentation, Dmitry
   Kirilyuk
 - #1038 capitalize header field for Location per RFC, Tommi Kyntola
 - #1011 update documentation to remove outdated references. fix more links,
   lukealbao
 - #1010 update documentation to include charSet property for static plugin,
   Greg Walker
 - #1000 update spdy to 3.2.0, Andy Tzeng
 - #1007 remove `defaultResponseHeaders` from documentation, lukealbao
 - #999 server `NotFound` handler is now normalized, works like other error
   events and no longer flushes responses automatically, Alex Liu
 - #991 update documentation links for new plugins and errors repo, Ken Warner
 - #987 disallow multiple values for content-type header, James O'Cull
 - #985 CORS removed from restify core. support `next(false)` in pre handler
   chains, Alex Liu
 - #982 allow sending of null body, Felix Milea-Ciobanu
 - #973 rev latest restify-errors, fix todoapp examples, Micah Ransdell
 - #972 added shrinkwrap+nsp for security vuln checks, Alex Liu
 - #971 Fix error creation when error message contain URI encoded characters,
   Benjamin Urban
 - #969 Fix incorrect usage of assert.AssertionError, Alex Liu
 - #965 added unit test for sending null body, Michael Nisi
 - #964 Fix cached routes not setting maxVersion, Alex Liu
 - #963 enhancements to res.redirect. server now emits `redirect` event, James
   Womack
 - #960 update documentation for websocket example, Richard Kiene
 - #958 RequestCaptureStream now writes triggering record, Gerrard Lindsay,
   Yunong Xiao
 - #955 update documentation for socket.io example, Thorsten Hans
 - #952 Formatters no longer set status codes or inspect payload, Christian
   Bongiorno, Alex Liu
 - #951 `res.sendRaw()` allows sending of responses without use of formatters,
   Matthew Amato, Alex Liu
 - #947 update documentation links for readme.md & badges, ReadmeCritic
 - #944 Support generic event listener, Alex Liu
 - #943 Fix typos in documentation, azollyx
 - #939 Fix issue where missing content-type header would hang response, Alex
   Liu
 - #935 Clearer docs for using certs, Vikram Tiwari
 - #932 Update to spdy 2.x, Fedor Indutny
 - #924 Update docs for async formatter breaking change, Magnus Wolffelt
 - #891 stop processing requests when 'close' event has been fired (early
   client termination), Alex Liu
 - #883 hypens no longer stripped from route names, Sean Wragg
 - #903 Update docs to reflect new error handling, Jacob Quatier
 - #889 Bump dependencies to latest, Micah Ransdell
 - #845 Support sync and async formatters, Alex Liu
 - #844 Move Errors to their own module, Alex Liu
 - #855 Clients now live in its own repo and npm module, Alex Liu
 - Various documentation improvements from leitsubomi

## 4.3.0

- #1024 Add `handleUncaughtExceptions` server option to supporting disabling
  the uncaughtException handler.

## 4.2.0

- #925 Support passing (most) [qs](https://github.com/ljharb/qs#readme) options
  to the `restify.queryParser` plugin. Update the "qs" dependency to latest (v6)
  while maintaining backward compatibility (see notes in the API doc and
  "test/query.test.js" on `allowDots` and `plainObjects`).

## 4.1.1

- update negotiator (NSP advisory #106) and lru-cache (bug fix).

## 4.1.0

- Bump SPDY to latest.
- #959: fix issue where cached routes were not setting maxVersion on the req

## 4.0.4

- #937 Fix missing content-type header causing response to hang

## 4.0.3
- #917 Fix: HTTP 413 status name, Micah Ransdell

## 4.0.2
- #887 Bump dtrace-provider to 0.6.0 for Node 4 support, Corbin Uselton

## 4.0.0
- #877 content-type can be case-insensitive. Yunong Xiao
- #856 update various dependencies. Alex Liu
- #851 **BREAKING** fix formatters such that they always return cb. Yunong Xiao
- #847 fix body parser race condition. Yunong Xiao
- #842 add `req.matchedVersion()` Nathan Peck, Micah Ransdell
- #840 Fix issue with server toString Method. OiNutter, Micah Ransdell
- #836 Add JSDoc comments. Alex Liu
- #835 Update static.js to allow for serving static files that do not use the route as a path. Wavewash, Micah Ransdell
- #831 Support hash option to Formidable for multipart file uploads. blakevanian, ManRueda
- #832 Updated dtrace-provider. yads
- #812 add query parameters to auditlogger. Alex Liu
- #800 Allow 0, false, and null as json body. Alex Dobeck
- #771 q-value choice on wildcards ignores default q-value of 1. Kevin Peno
- #822 Allow optional headers to be added as properties to bunyan logs. Michael Paulson.
- #824 Don't include large coverage files in published packages. Trent Mick
- #819 Add a feature to allow the expiration of old unprocessed requests. Michael Paulson
- #803 Add redirect support to Response. Alex Liu
- #686 `res.send` can't send 0, false and null. Alex Dobeck

## 3.0.3
- #669 Fix socket.io 1.x integration. Mark Doeswijk
- #662 Improve request logger doc. Jordan Klassen
- #793 Update Server API error event listener doc. github.com/durkes
- #795 Remove unused vars in source. James Womack
- #796 Hypermedia API fails when paths have multiple patterns with sub-regexs. Morten Fangel
- #775 Fix UTF-8 corruption in body parser. Michał Moskal

## 3.0.2
- #785 update semver dependency.

## 3.0.1
- #779 set-cookie headers should not include comma separated values. See:
  http://tools.ietf.org/html/rfc6265#section-3

## 3.0.0

- Bumping major because of #753

## 2.9.0

- #688 Fix various throttle bugs
- #691 Fix an issue where posting with text/csv content type crashes Restify
- #693 Support multiple response header values
- #704 Allow partial regex for named parameters
- #726 Allow per-request agent overrides
- #726 Ebanle `{agent: false}` option override per request
- #727 Fix JSON body parser behavior when request body is null
- #727 Fix a bug when `req.body === null`
- #731 SVG badges in README
- #734 Add API to track timers for nested handlers
- #744 Fix `request.isUpload` for PATCH requests
- #751 Fix `server.url` property when using IPv6
- #758 Switch to UUID v4
- #758 Use v4 UUIDs for `[x-]request-id`
- #759 Documentation fix
- #762 `res.noCache()` API to prevent all caching
- #767 Prefer the existing `err` serializer for audit logging
- Update dtrace-provider dependency
- #753 **BREAKING** Include `err` parameter for all \*Error events:
  Error events will all have the signature `function (req, res, err, cb)` to
  become consistent with the handling functionality introduced in 2.8.5.
  Error handlers using the `function (req, res, cb)` signature must be updated.

## 2.8.5

- Add ability to listen for error events
- Documentation fixes

## 2.8.4

- Update dtrace-provider, bunyan and backoff
- Fix request URL cache interaction with dtrace probes

## 2.8.3

- Support html5 multiple file uploads

## 2.8.2

- #619 Default to url, if string provided to createClient
- #614 do not compute the MD5 Hash of a partial content
- #516 Allow an `options` object to be passed into the authorization plugin
- Updating dependencies
- #626 Add more built-in errors to doc
- #460 Provide direct access to https server options if needed
- #656 update qs

## 2.8.1

- revert #604, work around by not removing client listener

## 2.8.0

- #604 trap http client errors
- #598 Simplify and correct path segment regexp
- #570 Route matching should only prefer later routes if version is greater
- #564 Using req.accepts() according to implementation
- #504 Helper to render a route with given parameters (for hypermedia APIs)

## 2.7.0

- #547 Added mapFiles option to bodyParser
- #552 PUT JsonClient test should use PUT not POST
- #550 Make router preflight code more readable
- #548 Allow custom handling of multipart data.

## 2.6.3

- Hotfix for CORS plugin if no origin was set in the options

## 2.6.2

- #508 add server option: `ciphers` to pass down to https(tls)
- #502 `server.on('request')` not emitting
- #496 static plugin incorrectly handling `directories`; revert back to 2.6.0
       version
- #495 don't override client response code with custom error object
- #494 socket connecting detection logic incorrect
- #492 client `false` needs to actually disable retries
- changed indent from four to eight
- #505 fix audit logger plugin bug
- #510 request timeout support
- #523 added Access-Control-Allow-Credentials to the preflight handler

## 2.6.1

- #478 Add `req.timers` to audit logging plugin.
- #487 RequestCaptureStream: dumpDefault, haveNonRawStreams, zero ring after dump
- #407 - bunyan 0.21.3
- Add CSV/TSV parser (Dominik Lessel)
- Add `req.timers`: a list of hrtime's for each handler
- Set TCP SO_KEEPALIVE when default KeepAliveAgent is on (client)

## 2.6.0

- EXPERIMENTAL: Native websocket support via watershed (Josh Clulow)
- Pass entire route, not just route.name to `after` (Dingman)
- Type coercion bug in Cache Control API (Chris Cannell)

## 2.5.1

- GH-401 RegEx routes stomp one another, resulting in 404
- GH-389 StringClient should handle garbage servers that send neither
         `Content-Length` nor `Transfer-Encoding: chunked` headers.

## 2.5.0

- Pick up http-signature@0.10.0 (breaking change, to those using it); see
  https://github.com/joyent/node-http-signature/issues/10
- GH-388 JSON client blows up on bad content
- GH-379 Static plugin: NotAuthorizedError for file path with
         parentheses (Ricardo Stuven)
- GH-370 Add charSet option for static file plugin (Jonathan Dahan)

## 2.4.1

- Support node 0.10.X TLS options in client(s)

## 2.4.0

- GH-368 Route /\/.*/ does not match request /? (Ben Hutchison)
- GH-366 `req.accepts()` not working with short-hand mime types
- GH-362 Empty body throws TypeError in StringClient (Bryan Donovan)
- GH-355 Serve gzip encoded files from static if they are available
         (Nathanael Anderson)
- GH-338 turn `req.body` into an `Object` when content-type is
         JSON (Daan Kuijsten)
- GH-336 `res.charSet()` back in
- dependency version bumps
- 0.10.X support in tests (add necessary `resume()` calls)
- client should log request/response pairs

## 2.3.5

- bunyan@0.20.0
- GH-346 `server.toString()` crashes (Alex Whitman)
- GH-193 support `next('name_of_route')`

## 2.3.4

- GH-343 default to 'identity' for accept-encoding
- GH-342 client support for PATCH
- Pick up spdy@1.4.6 (doesn't ship all the example garbage)

## 2.3.3

- Stop logging client_req in bunyan output
- GH-319 make DTrace optional
- GH-335 Content-Type'd routes not accepting array (Pedro Palazón)

## 2.3.2

- pick up bunyan 0.18.3
- server.address() returning null causes server.url to deref null

## 2.3.1

- GH-335 Content-Type'd routes not correct when only Accept-Extension varies,
         part deux (switch to `negotiator`, drop `mimeparse`).

## 2.3.0

- GH-335 Content-Type'd routes not correct when only Accept-Extension varies
- GH-332 Cache-Control max-age should show minutes (Ben Hutchison)
- GH-329 Wrong values in res.methods on some cases
- GH-327 server.versionedUse('1.2.3', function (req, res, next) {}) (Tim Kuijsten)
- GH-326 non-default origins not working, Chrome requires allow/origin and
         allow users to append to CORS array (John Fieber/Damon Oehlman)
- GH-323 <path>/?<querystring> broken
- GH-322 add `req.route`, which contains the original params for the
         route (Tim Kuijsten)
- GH-312 bodyParser() should return buffers when data is binary (Tim Kuijsten)
- GH-318 Allow use of 'requestBodyOnGet' option in bodyParser (@geebee)

## 2.2.1

- GH-283 broke versioned, typed routes. Fix.
- node-http-signature@0.9.11

## 2.2.0

- GH-316 drop `clone`, and just shallow copy (Trent Mick)
- GH-284 preflight requests not working without access-control-request-headers
- GH-283 versioned routes should use maximum match, not first (Colin O'Brien)
- dtrace probes for restify clients
- node-dtrace-provider@0.2.8
- backoff@2.0.0 and necessary changes

## 2.1.1

- revert to backoff@1.2.0

## 2.1.0

- GH-284 built-in CORS
- GH-290 next.ifError
- GH-291 fix overwriting `options.type` in createJSONClient (Trent Mick)
- GH-297 default document serving in static plugin (Adam Argo)
- GH-299 gzip plugin doesn't play nice with content-length (Ben Hale)
- GH-301 support private keys w/passphrase (Erik Kristensen)
- GH-302 responseTime cleanup
- Move to `node-backoff` and rework retry logic in HttpClient
- Support keep-alive by default in HttpClient

## 2.0.4

- GH-280 req.params cached by router
- RequestCaptureStream should support outputting to multiple streams
- Default uncaughtException handler should check if headers have been sent

## 2.0.2/2.0.3

- GH-278 missing events on route errors
- Undo `RestError` `constructorOpt` from 2.0.1

## 2.0.1

- GH-269 plugin to make curl happy
- RestError not honoring `constructorOpt` from `cause`
- GH-271 bump to dtrace 0.2.6 (fix build on Mountain Lion)

# Legacy Releases

## 1.4.2

- logging typo (Pedro Candel)
- response `beforeSend` event (Paul Bouzakis)

## 1.4.1

- GH-130 Allow restify and express to coexist.
- GH-129 format HttpErrors as well as RestErrors (Domenic Denicola)
- GH-127 add absolute uri to request (Paul Bouzakis)
- GH-124 `req.query` is `undefined` if no query string was sent
- GH-123 Generated DTrace probe names should be valid
- GH-122 Response._writeHead can cause infinite loop (Trent Mick)
- GH-120 Allow server.patch (Paul Bouzakis)
- GH-119 defaultResponseHeaders not settable
- GH-113 document `return next(false)`


## 1.4.0

- GH-116 More friendly error objects (Domenic Denicola)
- GH-115 Client hangs on server "hard kills" (i.e., RST)
- GH-111 JSON parser only works on objects (not arrays)
- GH-110 emit expectContinue (Paul Bouzakis)
- Fix "undefined" log message in string_client.js
- GH-107
  - Go back to hacking up http.prototype for performance reasons
  - Default to keep-alive on for HTTP/1.1 requests
  - Misc fixes after refactoring.
- GH-109 routes not honoring regex flags.
- GH-108 server missing `listening` event.
- Audit logger optionally logs request/response bodies
- Require http-signature@0.9.9/ctype@0.5.0 (node 0.7 compatible)

## 1.3.0

- GH-100 Make DTrace an optional dependency, and stub it out if not found.
- res.link API not allowing sprintf style sets.
- Support for `socketPath` in client API (alternative to url).
- OPTIONS api not returning access-control-allow-methods header (Steve Mason).
- Allow null passwords in HTTP basic auth (Andrew Robinson).
- set `req.files` on multipart file uploads (Andrew Robinson).

## 1.2.0

- Don't rely on instanceof checks for Errors in response.
- Change route.run log level from trace to debug on next(err).
- Add `res.link` API (wrap up sending a Link: response header).
- GH-98 req.secure needs to return a boolean, not an object
- GH-97 Malformed URI results in server crash
- GH-94 leverage `qs` module for object notation in query string.

## 1.1.1

- dependency version bumps
- res.header accepts sprintf-style arguments
- GH-95 Make restify compatible with node-logging (Andrew Robinson)
- GH-93 Minimal port of express pre-conditions (Dominic Barnes)
- GH-92 Make X-Response-Time configurable (Shaun Berryman)
- GH-87 server.listen on port as string (Andrew Sliwinski)

## 1.1.0

- GH-86 Bunyan version bump.
- Conditional Request plugin tests and fixes for some errors (Mike Williams).
- GH-83 pluggable storage engine for throttling, and LRU for default engine.
- GH-77 `server.on('uncaughtException', function (req, res, route, err) {});`
- GH-79 Docs typo(s).

## 1.0.1

- Version bump bunyan to 0.6.4.


## 1.0.0

- Makefile restructure (use Joyent templates)
- GH-20 HttpClient connectTimeout.
- Allow parser plugins to allow "override" params
- Proper handling of Expect: 100
- multipart/form-data plugin
- Added a 'header' event on res.writeHead
- GH-72 Wrong server name in response header on 404/405/...
- RegExp mounts throw a TypeError
- Allow pre handlers to update request url
- try/catch around route running
- Bundled audit logger (via bunyan)
- strict adherence to RFC3986 for URL encoding
- range versioning changed to be an array of explicit versions
- Switch from log4js to [bunyan](https://github.com/trentm/node-bunyan)
- Official version of `ConditionalRequest` plugin (Falco Nogatz)
- order formatters on response such that JSON/text are before custom ones
- RestErrors can use format strings
- date plugin has bad log check


## 1.0.0-rc2

- GH-66 Support for charSets in responses
- GH-65 Initial version of etag plugin (Falco Nogatz)
- GH-68 res.header() can serialize Date objects to RFC1123
- GH-67 Set some default response headers earlier (access-control-*)
- http-client should auto insert the date header
- GH-64 Support for a pre-routing chain
- JsonClient should "upcast" errors to RestErrors if it can
- GH-63 res.send(204) returning a body of 204
- GH-61 Make bodyParser merging into req.params optional
- Make Error objects backwards compatible with older restify (httpCode/restCode)
- GH-57, GH-62 range versioning on server (Diego Torres)
- GH-59 routes with just '/' are returning 404
- DTrace *-done actually firing content-length (was always 0)
- [Issue 56] Support streaming downloads
- Modify server.on('after') to emit the `Route` object, rather than the name.

## 1.0.0-rc1

(Started maintaining this log 21 January 2012. For earlier change information
you'll have to dig into the commit history.)


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Restify

Welcome to the restify community! This document is written both for maintainers and community members!

## Issues and PRs

### Commit Messages

When merging a PR, we squash and merge to keep our commit history clean. Our commit messages use the conventional changelog format (http://conventionalcommits.org/) to automagically manage semver for us.

### Labels and Templates

We try to keep things organized around here. Maintainers have a finite amount of time and are often juggling multiple things in their lives. Keeping things consistent and well labeled helps reduce the amount of concentration and effort required for us to both find and carry out work on the project. Simple things like using our templates and adding the appropriate labels may only take you a few minutes, but it can save cummulative hours worth of work for maintainers trying to digest dozens of issues.

## Website

### Design

The website templates are maintained at https://github.com/restify/restify.github.io and are populated from the docs directory in this repo.

### Releasing a change

To update the documentaiton on the website to reflect the latest version of 5.x simply:

```
git clone --recursive git@github.com:restify/restify.github.io
cd restify.github.io
git submodule update --remote && git add _docs && git commit -m 'bump' && git push origin master
```

The website will automatically deploy itself with the new changes.

### Updating a documentation page

To update docs, simply run:  

```
make docs-build
```

### Adding a documentation page

To add a new page, simply give it a [permalink](https://github.com/restify/node-restify/blob/94fe715173ffcebd8814bed7e17a22a24fac4ae8/docs/index.md) and then update [docs.yml](https://github.com/restify/restify.github.io/blob/master/_data/docs.yml) with the new permalink.

## Running a benchmark

```
make benchmark
```

## Cutting a release

Cutting a release is currently a manual process. We use a [Conventional Changelog](http://conventionalcommits.org/) to simplify the process of managing semver on this project. Generally, the following series of commands will cut a release from the `master` branch:

```
$ git fetch
$ git pull origin master # ensure you have the latest changes
$ npx unleash [-p for patch, -m for minor, -M for major] --no-publish -d # do a dry run to verify
$ npx unleash [-p for patch, -m for minor, -M for major] --no-publish 
# Unleash doesnt support 2FA, hence we use --no-publish flag here.
# This ensures we have the package.json updated, changelog generated, tag created
# and all the changes into origin
# Next, publish to npm manually and do not forget to provide the 2FA code.
$ npm publish
```


================================================
FILE: FEATURE_REQUESTS.md
================================================
Feature Requests
================

While the maintainers of restify work hard to provide the best possible
framwork for building REST services, there is more work to go around than there
are hours in the day. This document contains a set of features that have been
requested by the community. If you are looking to contribute, the items on
this list -- along with the open bugs on the issues tab -- are a great place to
start!

> The features here are not sorted in any particular order. Each feature links
> to the original GitHub issue requesting it. While feature requests are
> generally closed and moved to this document, discussion around the feature
> still takes place on the original issue. Even if there has been a discussion
> on the issue already, it is still worth declaring your intent to open a PR
> before investing time in writing code.

## Code

* [Support `server.use(route, handler)` and `server.all`][289]
* [Support asynchronous callbacks for throttle][381]
* [Streaming multipart parser without needing temporary files][474]
* [Default client to http protocol][790]
* [Exponential backoff and retry][633]
* [Arbitrary HTTP methods][576]
* [Detect route conflicts][909]
* [Improve upon `next.ifError`][875]
* [Benchmark suite][860]
* [HTTP/2 support][853]
* [Improve performance of route lookup][850]
* [Support HTTP_PROXY][813]
* [IE9 support for `bodyParser`][801]
* [Multipart Client Support][921]
* [Remove `next(err)`][1019]
* [Support `RegExp` for `route.render`][632]
* [Run internal handlers on `NotFound`][708]
* [Support multiple apps on the same port][1035]
* [Multiple versions for routes][1134]
* [sysdig support][1323]
* [Migrate routing DSL to `path-to-regexp`][1292]
* [JQuery Style Query Expansion][895]
* [Support Proxy Protocol][1046]

## Documentation

* [Socket.io support][717]
* [`uncaughtException` handler when opting into domains][829]
* [Forward `req_id`][1101]
* [Document `bodyParser` headers][989]
* [Improve signRequest documentation][737]
* [Better documentation for `client.close`][859]
* [Document all client options][1326]
* [Client tunneling vs. proxying][1327]
* [Explain why Restify is great!][927]
* [`BasicAuth` examples][1099]
* [Document `next` behaviour][1068]
* [Remove defaultResponseHeaders][1040]
* [Properly document req.accepts][957]
* [Plugin custom errors][948]
* [`findByPath` on `Router`][1136]
* [Multiple route handlers][1183]
* [Update new `HttpError` codes][1206]
* [v4 res.headers][1286]
* [Document RegExp DSL for routing][1065]

[289]: https://github.com/restify/node-restify/issues/289
[381]: https://github.com/restify/node-restify/issues/381
[474]: https://github.com/restify/node-restify/issues/474
[575]: https://github.com/restify/node-restify/issues/575
[790]: https://github.com/restify/node-restify/issues/790
[633]: https://github.com/restify/node-restify/issues/663
[717]: https://github.com/restify/node-restify/issues/717#issuecomment-296531086
[576]: https://github.com/restify/node-restify/issues/576
[576]: https://github.com/restify/node-restify/issues/576
[909]: https://github.com/restify/node-restify/issues/909
[875]: https://github.com/restify/node-restify/issues/875
[860]: https://github.com/restify/node-restify/issues/860
[853]: https://github.com/restify/node-restify/issues/853
[850]: https://github.com/restify/node-restify/issues/850
[829]: https://github.com/restify/node-restify/issues/829
[813]: https://github.com/restify/node-restify/issues/813
[801]: https://github.com/restify/node-restify/issues/801
[921]: https://github.com/restify/node-restify/issues/921
[1101]: https://github.com/restify/node-restify/issues/1101
[1019]: https://github.com/restify/node-restify/issues/1019
[989]: https://github.com/restify/node-restify/issues/989
[632]: https://github.com/restify/node-restify/issues/632
[708]: https://github.com/restify/node-restify/issues/708
[737]: https://github.com/restify/node-restify/issues/737
[859]: https://github.com/restify/node-restify/issues/859
[1326]: https://github.com/restify/node-restify/issues/1326
[1327]: https://github.com/restify/node-restify/issues/1327
[927]: https://github.com/restify/node-restify/issues/927
[1099]: https://github.com/restify/node-restify/issues/1099
[1068]: https://github.com/restify/node-restify/issues/1068
[1040]: https://github.com/restify/node-restify/issues/1040
[1035]: https://github.com/restify/node-restify/issues/1035
[957]: https://github.com/restify/node-restify/issues/957
[948]: https://github.com/restify/node-restify/issues/948
[1134]: https://github.com/restify/node-restify/issues/1134
[1136]: https://github.com/restify/node-restify/issues/1136
[1183]: https://github.com/restify/node-restify/issues/1183
[1206]: https://github.com/restify/node-restify/issues/1206
[1286]: https://github.com/restify/node-restify/issues/1286
[1323]: https://github.com/restify/node-restify/issues/1323
[1292]: https://github.com/restify/node-restify/issues/1292
[1065]: https://github.com/restify/node-restify/pull/1065
[895]: https://github.com/restify/node-restify/issues/895
[1046]: https://github.com/restify/node-restify/pull/1046


================================================
FILE: LICENSE
================================================
Copyright (c) 2011 Mark Cavage, All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE


================================================
FILE: Makefile
================================================
#
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
#
# Makefile: basic Makefile for template API service
#
# This Makefile is a template for new repos. It contains only repo-specific
# logic and uses included makefiles to supply common targets (javascriptlint,
# jsstyle, restdown, etc.), which are used by other repos as well. You may well
# need to rewrite most of this file, but you shouldn't need to touch the
# included makefiles.
#
# If you find yourself adding support for new targets that could be useful for
# other projects too, you should add these to the original versions of the
# included Makefiles (in eng.git) so that other teams can use them too.
#

#
# Tools
#
ESLINT		:= ./node_modules/.bin/eslint
DOCUMENTATION		:= ./node_modules/.bin/documentation
NODEUNIT	:= ./node_modules/.bin/nodeunit
MOCHA		:= ./node_modules/.bin/mocha
NODECOVER	:= ./node_modules/.bin/nyc
DOCS_BUILD	:= ./tools/docsBuild.js
NPM		:= npm
NODE		:= node
PRETTIER		:= ./node_modules/.bin/prettier

#
# Files
#
JS_FILES	 = '.'

CLEAN_FILES	+= node_modules cscope.files

include ./tools/mk/Makefile.defs

#
# Repo-specific targets
#
.PHONY: all
all: $(NODEUNIT) $(REPO_DEPS)
	$(NPM) rebuild

$(NODEUNIT): | $(NPM_EXEC)
	$(NPM) install

$(NODECOVER): | $(NPM_EXEC)
	$(NPM) install

.PHONY: cover
cover: $(NODECOVER)
	@rm -fr ./.coverage_data
	$(NODECOVER) --reporter=html --reporter=text-summary --reporter=lcov $(NODEUNIT) ./test/*.js

CLEAN_FILES += $(TAP) ./node_modules/nodeunit

.PHONY: test
test: $(NODEUNIT)
	$(NODEUNIT) test/*.test.js
	$(MOCHA) --full-trace --no-exit test/plugins/*.test.js

.PHONY: docs-build
docs-build:
	@($(NODE) $(DOCS_BUILD))

.PHONY: benchmark
benchmark:
	@(cd ./benchmark && $(NPM) i && $(NODE) index.js)

include ./tools/mk/Makefile.deps
include ./tools/mk/Makefile.targ


================================================
FILE: README.md
================================================
<!-- Please don't remove this: Grab your social icons from https://github.com/carlsednaoui/gitsocial -->

<!-- display the social media buttons in your README -->

[![alt text][1.1]][1]


<!-- links to social media icons -->
<!-- no need to change these -->

<!-- icons with padding -->

[1.1]: http://i.imgur.com/tXSoThF.png (twitter icon with padding)

<!-- icons without padding -->

[1.2]: http://i.imgur.com/wWzX9uB.png (twitter icon without padding)


<!-- links to your social media accounts -->
<!-- update these accordingly -->

[1]: http://www.twitter.com/restifyjs

<!-- Please don't remove this: Grab your social icons from https://github.com/carlsednaoui/gitsocial -->

![restify](/../gh-images/logo/png/restify_logo_black_transp_288x288.png?raw=true "restify")

[![Build Status](https://travis-ci.org/restify/node-restify.svg?branch=master)](https://travis-ci.org/restify/node-restify)
[![Dependency Status](https://david-dm.org/restify/node-restify.svg)](https://david-dm.org/restify/node-restify)
[![devDependency Status](https://david-dm.org/restify/node-restify/dev-status.svg)](https://david-dm.org/restify/node-restify#info=devDependencies)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)

[restify](http://restify.com) is a framework, utilizing
[connect](https://github.com/senchalabs/connect) style middleware for building
REST APIs.  For full details, see http://restify.com

Follow restify on [![alt text][1.2]][1]

# Usage

## Server
```javascript
var restify = require('restify');

const server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});

server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser());

server.get('/echo/:name', function (req, res, next) {
  res.send(req.params);
  return next();
});

server.listen(8080, function () {
  console.log('%s listening at %s', server.name, server.url);
});
```

## Client
```javascript
var assert = require('assert');
var clients = require('restify-clients');

var client = clients.createJsonClient({
  url: 'http://localhost:8080',
  version: '~1.0'
});

client.get('/echo/mark', function (err, req, res, obj) {
  assert.ifError(err);
  console.log('Server returned: %j', obj);
});
```

# Installation
```bash
$ npm install restify
```

## Supported Node Versions

Restify currently works on Node.js v14.x and v16.x.

## License

The MIT License (MIT)

Copyright (c) 2018 restify

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

## Bugs

See <https://github.com/restify/node-restify/issues>.

## Other repositories

- For the errors module, please go [here](https://github.com/restify/errors).


## Mailing list

See the
[Google group](https://groups.google.com/forum/?hl=en&fromgroups#!forum/restify)
.


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Reporting a Vulnerability

Do not disclose vulnerabilities in public issues. Please report vulnerabilities to
security@restify.com with steps to reproduce the vulnerability, and a patch to fix
it if possible.


================================================
FILE: benchmark/benchmarks/middleware.js
================================================
'use strict';

var restify = process.argv.includes('version=head')
    ? require('../../lib')
    : require('restify');

var server = restify.createServer();
var path = '/';
var port = 3000;

module.exports = {
    url: 'http://localhost:' + port + path
};

function handler(req, res, next) {
    next();
}

for (var i = 0; i < 10; i++) {
    server.pre(handler);
}

for (var j = 0; j < 10; j++) {
    server.use(handler);
}

server.get(path, function get(req, res) {
    res.send('hello world');
});

if (!module.parent) {
    server.listen(port);
}


================================================
FILE: benchmark/benchmarks/response-json.js
================================================
'use strict';

var restify = process.argv.includes('version=head')
    ? require('../../lib')
    : require('restify');

var server = restify.createServer();
var path = '/';
var port = 3000;

module.exports = {
    url: 'http://localhost:' + port + path
};

server.get(path, function onRequest(req, res) {
    res.send({ hello: 'world' });
});

if (!module.parent) {
    server.listen(port);
}


================================================
FILE: benchmark/benchmarks/response-text.js
================================================
'use strict';

var restify = process.argv.includes('version=head')
    ? require('../../lib')
    : require('restify');

var server = restify.createServer();
var path = '/';
var port = 3000;

module.exports = {
    url: 'http://localhost:' + port + path
};

server.get(path, function onRequest(req, res) {
    res.send('hello world');
});

if (!module.parent) {
    server.listen(port);
}


================================================
FILE: benchmark/benchmarks/router-heavy.js
================================================
'use strict';

var restify = process.argv.includes('version=head')
    ? require('../../lib')
    : require('restify');

var server = restify.createServer();
var path = '/whiskeys/scotch/islay/lagavulin/16-years/50';
var methods = ['post', 'put', 'get', 'del', 'patch'];
var _ = require('lodash');
var port = 3000;

// Disabling cache: it's not fair as it aims to the worst case, when
// cache hit ratio is 0%. However, it's still better than the worst
// as it doesn't require extra time to maintain the LRU cache.
// There is no other way to simulate 100+ different endpoint
// calls with the current benchmark suite.
if (!process.argv.includes('version=head')) {
    server.router.cache = {
        get: function get() {
            return null;
        },
        set: function get() {
            return null;
        },
        dump: function get() {
            return [];
        }
    };
}

module.exports = {
    url: 'http://localhost:' + port + path
};

var routes = {
    beers: {
        ale: {
            'pale-ale': {
                'american-pale-ale': [],
                'indian-pale-ale': []
            },
            lambic: [],
            stout: {
                'american-porter': [],
                'imperial-stout': [],
                'irish-stout': []
            }
        },
        lager: {
            'german-lager': {
                marzen: []
            },
            pilsner: {
                'german-pilsner': []
            }
        }
    },

    whiskeys: {
        american: {
            bourbon: {
                kentchuky: {
                    'jim-beam': ['jim-beam', 'bookers', 'old-crow'],
                    'makers-mark': ['makers-mark'],
                    'woodford-reserve': ['woodford-reserve']
                },
                tennessee: {
                    'jack-daniels': ['jack-daniels']
                }
            },
            rye: {
                'beam-suntory': ['jim-beam-rye', 'knob-creek']
            }
        },
        irish: {
            'single-malt': {
                bushmills: ['bushmills'],
                connemare: ['connemare']
            },
            'single-pot': {
                redbreast: ['redbreast'],
                jameson: ['jameson-15-year']
            }
        },
        japanese: {
            nikka: ['coffeey-malt', 'blended', 'from-the-barrel'],
            hibiki: ['japanese-harmony'],
            yamazakura: ['blended']
        },
        scotch: {
            islay: {
                bruichladdich: ['25-years', 'islay-barley-2009'],
                octomore: ['7.2', 'islay-barley-8.3'],
                laphroaig: ['lore', '15-years', 'four-oak'],
                lagavulin: ['distillers-edition', '8-years', '16-years']
            }
        }
    }
};

function handler(req, res) {
    res.send('hello');
}

function attachRoute(parent, routeConfig) {
    _.map(routeConfig, function map(route, routeKey) {
        var pathChunk = _.isString(routeKey) ? routeKey : route;
        var routePath = parent + '/' + pathChunk;

        methods.forEach(function forEach(method) {
            server[method](routePath, handler);
        });

        if (_.isObject(route) || _.isArray(route)) {
            attachRoute(routePath, route);
        }
        if (_.isString(route)) {
            for (var i = 0; i <= 100; i++) {
                methods.forEach(function forEach(method) {
                    server[method](routePath + '/' + i, handler);
                });
            }
        }
    });
}

attachRoute('', routes);

if (!module.parent) {
    server.listen(port);
}


================================================
FILE: benchmark/index.js
================================================
#!/usr/bin/env node
'use strict';

var inquirer = require('inquirer');
var bench = require('./lib/bench');
var stableVersion = require('restify/package.json').version;

var BENCHMARKS = [
    'response-json',
    'response-text',
    'router-heavy',
    'middleware'
];

function select(callback) {
    var choices = BENCHMARKS.map(function map(name) {
        return {
            name: name,
            checked: true
        };
    });

    choices.unshift(new inquirer.Separator(' = The usual ='));

    inquirer
        .prompt([
            {
                type: 'checkbox',
                message: 'Select packages',
                name: 'list',
                choices: choices,
                validate: function validate(answer) {
                    if (answer.length < 1) {
                        return 'You must choose at least one package.';
                    }
                    return true;
                }
            }
        ])
        .then(function onPrompted(answers) {
            callback(answers.list);
        });
}

inquirer
    .prompt([
        {
            type: 'confirm',
            name: 'track',
            message: 'Do you want to track progress?',
            default: false
        },
        {
            type: 'confirm',
            name: 'compare',
            message:
                'Do you want to compare HEAD with the stable release (' +
                stableVersion +
                ')?',
            default: true
        },
        {
            type: 'confirm',
            name: 'all',
            message: 'Do you want to run all benchmark tests?',
            default: true
        },
        {
            type: 'input',
            name: 'connection',
            message: 'How many connections do you need?',
            default: 100,
            validate: function validate(value) {
                return (
                    !Number.isNaN(parseFloat(value)) || 'Please enter a number'
                );
            },
            filter: Number
        },
        {
            type: 'input',
            name: 'pipelining',
            message: 'How many pipelining do you need?',
            default: 10,
            validate: function validate(value) {
                return (
                    !Number.isNaN(parseFloat(value)) || 'Please enter a number'
                );
            },
            filter: Number
        },
        {
            type: 'input',
            name: 'duration',
            message: 'How long does it take?',
            default: 30,
            validate: function validate(value) {
                return (
                    !Number.isNaN(parseFloat(value)) || 'Please enter a number'
                );
            },
            filter: Number
        }
    ])
    .then(function validate(opts) {
        if (!opts.all) {
            select(function onSelected(list) {
                bench(opts, list);
            });
        } else {
            bench(opts, BENCHMARKS);
        }
    });


================================================
FILE: benchmark/lib/autocannon.js
================================================
'use strict';

var autocannon = require('autocannon');
var fs = require('fs');
var autocannonCompare = require('autocannon-compare');
var path = require('path');

var resultsDirectory = path.join(__dirname, '../results');

function writeResult(handler, version, result) {
    try {
        fs.accessSync(resultsDirectory);
    } catch (e) {
        fs.mkdirSync(resultsDirectory);
    }

    result.server = handler;

    var dest = path.join(resultsDirectory, handler + '-' + version + '.json');
    return fs.writeFileSync(dest, JSON.stringify(result, null, 4));
}

function fire(opts, handler, version, save, cb) {
    opts = opts || {};
    opts.url = opts.url || 'http://localhost:3000';

    var instance = autocannon(opts, function onResult(err, result) {
        if (err) {
            cb(err);
            return;
        }

        if (save) {
            writeResult(handler, version, result);
        }

        cb();
    });

    if (opts.track && save) {
        autocannon.track(instance);
    }
}

function compare(handler) {
    var resStable = require(resultsDirectory + '/' + handler + '-stable.json');
    var resHead = require(resultsDirectory + '/' + handler + '-head.json');
    var comp = autocannonCompare(resStable, resHead);
    var result = {
        throughput: {
            significant: comp.throughput.significant
        }
    };

    if (comp.equal) {
        result.throughput.equal = true;
    } else if (comp.aWins) {
        result.throughput.equal = false;
        result.throughput.wins = 'stable';
        result.throughput.diff = comp.throughput.difference;
    } else {
        result.throughput.equal = false;
        result.throughput.wins = 'head';
        result.throughput.diff = autocannonCompare(
            resHead,
            resStable
        ).throughput.difference;
    }

    return result;
}

module.exports = {
    fire: fire,
    compare: compare
};


================================================
FILE: benchmark/lib/bench.js
================================================
#!/usr/bin/env node
'use strict';

var fork = require('child_process').fork;
var ora = require('ora');
var path = require('path');
var autocannon = require('./autocannon');
var pipeline = require('vasync').pipeline;

function runBenchmark(opts, handler, version, cb) {
    if (opts.track) {
        console.log(version.toUpperCase() + ':');
    }

    var spinner = ora('Started ' + version + '/' + handler).start();
    var modulePath = path.join(__dirname, '../benchmarks', handler);
    var url = require(modulePath).url;
    var forked = fork(modulePath, ['version=' + version]);

    pipeline(
        {
            funcs: [
                function warm(_, callback) {
                    spinner.color = 'magenta';
                    spinner.text =
                        'Warming ' + version + '/' + handler + ' for 5s';

                    var fireOpts = Object.assign({}, opts, {
                        duration: 5,
                        url: url
                    });
                    autocannon.fire(
                        fireOpts,
                        handler,
                        version,
                        false,
                        callback
                    );
                },

                function benchmark(_, callback) {
                    if (opts.track) {
                        spinner.stop();
                    } else {
                        spinner.color = 'yellow';
                        spinner.text =
                            'Benchmarking ' +
                            version +
                            '/' +
                            handler +
                            ' for ' +
                            opts.duration +
                            's';
                    }

                    var fireOpts = Object.assign({}, opts, { url: url });
                    autocannon.fire(fireOpts, handler, version, true, callback);
                }
            ]
        },
        function onPipelineFinished(err) {
            forked.kill('SIGINT');

            if (err) {
                spinner.fail();
                cb(err);
                return;
            }

            spinner.text = 'Results saved for ' + version + '/' + handler;
            spinner.succeed();

            cb();
        }
    );
}

function start(opts, list, index) {
    index = index || 0;

    // No more item
    if (list.length === index) {
        return;
    }

    var handler = list[index];
    console.log('---- ' + handler + ' ----');

    pipeline(
        {
            funcs: [
                function head(_, callback) {
                    runBenchmark(opts, handler, 'head', callback);
                },
                function stable(_, callback) {
                    if (!opts.compare) {
                        callback();
                        return;
                    }
                    runBenchmark(opts, handler, 'stable', callback);
                }
            ]
        },
        function onPipelineFinished(err) {
            if (err) {
                console.log(err);
                return;
            }

            // Compare versions
            if (opts.compare) {
                var result = autocannon.compare(handler);

                console.log(handler + ' throughput:');
                console.log(JSON.stringify(result.throughput, null, 4) + '\n');
            }

            // Benchmark next handler
            start(opts, list, ++index);
        }
    );
}

module.exports = start;


================================================
FILE: benchmark/package.json
================================================
{
  "name": "restify-benchmark",
  "homepage": "http://restifyjs.com",
  "description": "Restify benchmark",
  "version": "0.0.0",
  "private": true,
  "main": "index.js",
  "engines": {
    "node": ">=0.10"
  },
  "dependencies": {
    "restify": "latest"
  },
  "devDependencies": {},
  "license": "MIT",
  "scripts": {
    "start": "node indec"
  }
}


================================================
FILE: bin/report-latency
================================================
#!/usr/bin/env node
// -*- mode: js -*-

var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var readline = require('readline');
var sprintf = require('util').format;

var nopt = require('nopt');


///--- Globals

var BUCKETS = {};
var REQUEST_IDS = {};

var OPTS = {
    'average': Boolean,
    'help': Boolean,
    'end': Date,
    'max-latency': Number,
    'max-requests': Number,
    'output': String,
    'percentile': [Number, Array],
    'period': Number,
    'requests': Boolean,
    'start': Date
};

var SHORT_OPTS = {
    'a': ['--average'],
    'h': ['--help'],
    'i': ['--period'],
    'e': ['--end'],
    'l': ['--max-latency'],
    'n': ['--max-requests'],
    'o': ['--output'],
    'p': ['--percentile'],
    'r': ['--requests'],
    's': ['--start']
};


///--- Functions

function percentile(p, vals) {
    p = parseInt(p, 10);
    return vals[(Math.round(((p / 100) * vals.length) + 1 / 2) - 1)].latency;
}


function report(buckets, output) {
    Object.keys(buckets).sort(function (a, b) {
        return parseInt(a, 10) - parseInt(b, 10);
    }).forEach(function (k) {
            var avg = 0;
            var perc = [];
            var req = buckets[k].length;
            var sum = 0;
            var t = Math.round(buckets[k]._time);

            buckets[k] = buckets[k].sort(function (a, b) {
                return a.latency - b.latency;
            });

            buckets[k].forEach(function (v) {
                sum += v.latency;
            });

            if (sum > 0 && req > 0) {
                if (output.average)
                    output.average.push([t, Math.round(sum / req)]);
                if (output.requests)
                    output.requests.push([t, buckets[k].length]);
                Object.keys(output.percentile).forEach(function (p) {
                    var _p = percentile(p, buckets[k]);
                    output.percentile[p].push([t, _p]);
                });
            }
        });

    return output;
}


function usage(code, message) {
    var str = '';
    Object.keys(SHORT_OPTS).forEach(function (k) {
        if (!Array.isArray(SHORT_OPTS[k]))
            return;

        var opt = SHORT_OPTS[k][0].replace('--', '');
        var type = OPTS[opt].name || 'string';
        if (type && type === 'boolean')
            type = '';
        type = type.toLowerCase();

        str += ' [--' + opt + ' ' + type + ']';
    });
    str += ' [file ...]';

    if (message)
        console.error(message);

    console.error('usage: ' + path.basename(process.argv[1]) + str);
    process.exit(code);
}


///--- Mainline

var parsed;

try {
    parsed = nopt(OPTS, SHORT_OPTS, process.argv, 2);
} catch (e) {
    usage(1, e.toString());
}

if (parsed.help)
    usage(0);
if (!parsed.average && !parsed.percentile)
    usage(1, '--average or --percentile required');
if (parsed.argv.remain.length < 1)
    usage(1, 'log file required');

var config = {
    average: parsed.average || false,
    maxLatency: parsed['max-latency'] || 1000,
    maxRequests: parsed['max-requests'] || 10000,
    percentile: parsed.percentile || [],
    period: parsed.period || 60,
    requests: parsed.requests || false,
    start: parsed.start ? (parsed.start.getTime() / 1000) : 0,
    end: parsed.end ? (parsed.end.getTime() / 1000) : Number.MAX_VALUE
};

var buckets = {};

var done = 0;
parsed.argv.remain.forEach(function (f) {
    var stream = readline.createInterface({
        input: fs.createReadStream(f),
        output: null
    })
    stream.on('line', function (l) {
        var record;
        var t = -1;

        try {
            record = JSON.parse(l);
        } catch (e) {
        }

        if (!record)
            return;

        var t = -1;
        if (record.time)
            t = (new Date(record.time).getTime() / 1000);

        if (record._audit !== true ||
            REQUEST_IDS[record.req_id] ||
            t < config.start ||
            t > config.end) {

            console.error('Skipping %s', l);
        }

        REQUEST_IDS[record.req_id] = true;
        record.time = t;

        var b = Math.round(record.time / config.period) + '';
        if (!buckets[b])
            buckets[b] = [];

        buckets[b].push(record);
        buckets[b]._time = record.time // good enough
    });

    stream.on('end', function () {
        if (++done === parsed.argv.remain.length) {
            console.error('Generating report...');

            var output = {
                average: config.average ? [] : false,
                requests: config.requests ? [] : false,
                percentile: {}
            };
            config.percentile.forEach(function (p) {
                output.percentile[p] = [];
            });

            output = report(buckets, output);
            var finalOutput = [];
            if (output.average) {
                finalOutput.push({
                    name: 'avg',
                    values: output.average
                });
            }
            if (output.requests) {
                finalOutput.push({
                    name: 'n',
                    values: output.requests
                });
            }
            Object.keys(output.percentile).forEach(function (k) {
                finalOutput.push({
                    name: 'p' + k,
                    values: output.percentile[k]
                });
            });

            console.log(JSON.stringify(finalOutput));
        }
    });
});


================================================
FILE: docs/_api/formatters.md
================================================
---
title: Formatters API
permalink: /docs/formatters-api/
---

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

-   [Usage][1]
-   [Types][2]
    -   [formatter][3]
-   [Included formatters][4]
    -   [formatText][5]
    -   [formatJSON][6]
    -   [formatJSONP][7]
    -   [formatBinary][8]

## Usage

Restify comes bundled with a selection of useful formatters that prepare your
responses for being sent over the wire, but you are free to include your own!

```js
function formatGraphQL(req, res, body) {
    var data = body;
    /* Do a thing to data */
    res.setHeader('Content-Length', Buffer.byteLength(data));
    return data;
}

var server = restify.createServer({
    formatters: {
        'application/graphql': formatGraphQL
    }
});

// Your application now supports content-type 'application/graphql'
```


## Types




### formatter

Format a response for being sent over the wire

Type: [Function][9]

**Parameters**

-   `req` **[Object][10]** the request object (not used)
-   `res` **[Object][10]** the response object
-   `body` **[Object][10]** response body to format

Returns **[String][11]** formatted response data

## Included formatters

restify comes pre-loaded with a standard set of formatters for common
use cases.


### formatText

Formats the body to 'text' by invoking a toString() on the body if it
exists. If it doesn't, then the response is a zero-length string.

**Parameters**

-   `req` **[Object][10]** the request object (not used)
-   `res` **[Object][10]** the response object
-   `body` **[Object][10]** response body. If it has a toString() method this
                              will be used to make the string representation

Returns **[String][11]** data

### formatJSON

JSON formatter. Will look for a toJson() method on the body. If one does not
exist then a JSON.stringify will be attempted.

**Parameters**

-   `req` **[Object][10]** the request object (not used)
-   `res` **[Object][10]** the response object
-   `body` **[Object][10]** response body

Returns **[String][11]** data

### formatJSONP

JSONP formatter. like JSON, but with a callback invocation.
Unicode escapes line and paragraph separators.

**Parameters**

-   `req` **[Object][10]** the request object
-   `res` **[Object][10]** the response object
-   `body` **[Object][10]** response body

Returns **[String][11]** data

### formatBinary

Binary formatter.

**Parameters**

-   `req` **[Object][10]** the request object
-   `res` **[Object][10]** the response object
-   `body` **[Object][10]** response body

Returns **[Buffer][12]** body

[1]: #usage

[2]: #types

[3]: #formatter

[4]: #included-formatters

[5]: #formattext

[6]: #formatjson

[7]: #formatjsonp

[8]: #formatbinary

[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[12]: https://nodejs.org/api/buffer.html


================================================
FILE: docs/_api/plugins.md
================================================
---
title: Plugins API
permalink: /docs/plugins-api/
---

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

-   [Usage][1]
-   [server.pre() plugins][2]
    -   [context][3]
    -   [dedupeSlashes][4]
    -   [pause][5]
    -   [sanitizePath][6]
    -   [reqIdHeaders][7]
    -   [strictQueryParams][8]
    -   [userAgentConnection][9]
-   [server.use() plugins][10]
    -   [acceptParser][11]
    -   [authorizationParser][12]
    -   [dateParser][13]
    -   [queryParser][14]
    -   [jsonp][15]
    -   [bodyParser][16]
    -   [requestLogger][17]
    -   [gzipResponse][18]
    -   [serveStatic][19]
    -   [serveStaticFiles][20]
    -   [throttle][21]
    -   [requestExpiry][22]
        -   [Using an external storage mechanism for key/bucket mappings.][23]
    -   [inflightRequestThrottle][24]
    -   [cpuUsageThrottle][25]
    -   [conditionalHandler][26]
    -   [conditionalRequest][27]
    -   [auditLogger][28]
    -   [metrics][29]
-   [Types][30]
    -   [metrics~callback][31]
-   [req.set][32]
-   [req.get][33]
-   [req.getAll][34]

## Usage

Restify comes bundled with a selection of useful plugins. These are accessible
off of `restify.plugins` and `restify.pre`.

```js
var server = restify.createServer();
server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.authorizationParser());
server.use(restify.plugins.dateParser());
server.use(restify.plugins.queryParser());
server.use(restify.plugins.jsonp());
server.use(restify.plugins.gzipResponse());
server.use(restify.plugins.bodyParser());
server.use(restify.plugins.requestExpiry());
server.use(restify.plugins.throttle({
  burst: 100,
  rate: 50,
  ip: true,
  overrides: {
    '192.168.1.1': {
      rate: 0,        // unlimited
      burst: 0
    }
  }
}));
server.use(restify.plugins.conditionalRequest());
```


## server.pre() plugins

This module includes various pre plugins, which are intended to be used prior
to routing of the URL. To use a plugin before routing, use the `server.pre()`
method.


### context

This plugin creates `req.set(key, val)` and `req.get(key)` methods for
setting and retrieving request specific data.

**Examples**

```javascript
server.pre(restify.plugins.pre.context());
server.get('/', [
    function(req, res, next) {
        req.set(myMessage, 'hello world');
        return next();
    },
    function two(req, res, next) {
        res.send(req.get(myMessage)); // => sends 'hello world'
        return next();
    }
]);
```

Returns **[Function][35]** Handler

### dedupeSlashes

This plugin deduplicates extra slashes found in the URL. This can help with
malformed URLs that might otherwise get misrouted.

**Examples**

```javascript
server.pre(restify.plugins.pre.dedupeSlashes());
server.get('/hello/:one', function(req, res, next) {
    res.send(200);
    return next();
});

// the server will now convert requests to /hello//jake => /hello/jake
```

Returns **[Function][35]** Handler

### pause

This pre handler fixes issues with node hanging when an `asyncHandler` is
used prior to `bodyParser`.
[https://github.com/restify/node-restify/issues/287][36]
[https://github.com/restify/node-restify/issues/409][37]
[https://github.com/restify/node-restify/wiki/1.4-to-2.0-Migration-Tips][38]

Returns **[Function][35]** Handler

### sanitizePath

Cleans up sloppy URLs on the request object,
like `/foo////bar///` to `/foo/bar`.

Returns **[Function][35]** Handler

### reqIdHeaders

This plugin pulls the value from an incoming request header and uses it
as the value of the request id. Subsequent calls to `req.id()`
will return the header values.

**Parameters**

-   `opts` **[Object][39]** an options object
    -   `opts.headers` **[Array][40]&lt;[String][41]>** array of headers from where to pull existing
                                       request id headers. Lookup precedence
                                       is left to right (lowest index first)

Returns **[Function][35]** Handler

### strictQueryParams

Prevents `req.urls` non-strict key-value query params

The Request-URI is transmitted in the format specified in section 3.2.1.
If the Request-URI is encoded using the "% HEX HEX" encoding [42],
the origin server MUST decode the Request-URI
in order to properly interpret the request.
Servers SHOULD respond to invalid Request-URIs
with an appropriate status code.

part of Hypertext Transfer Protocol -- HTTP/1.1 | 5.1.2 Request-URI
RFC 2616 Fielding, et al.

**Parameters**

-   `options` **[Object][39]?** an options object
    -   `options.message` **[String][41]?** a custom error message
                                     default value:
                                     "Url query params does not meet strict format"

Returns **[Function][35]** Handler

### userAgentConnection

This basically exists for `curl`. `curl` on `HEAD` requests usually
just sits there and hangs, unless you explicitly set
Connection:close. And in general, you probably want to set
Connection: close to curl anyway.

Also, because curl spits out an annoying message to stderr about
remaining bytes if content-length is set, this plugin also drops
the `content-length` header (some user agents handle it and want it,
curl does not).

To be slightly more generic, the options block takes a user
agent regexp, however.

**Parameters**

-   `options` **[Object][39]?** an options object
    -   `options.userAgentRegExp` **[RegExp][42]** matching any
                                                               user-agents applicable (optional, default `/^curl.+/`)

Returns **[Function][35]** Handler

## server.use() plugins




### acceptParser

Parses the `Accept` header, and ensures that the server can respond to what
the client asked for. In almost all cases passing in `server.acceptable` is
all that's required, as that's an array of content types the server knows
how to respond to (with the formatters you've registered). If the request is
for a non-handled type, this plugin will return a `NotAcceptableError` (406).

Note you can get the set of types allowed from a restify server by doing
`server.acceptable`.

**Parameters**

-   `accepts` **[Array][40]&lt;[String][41]>** array of accept types.

**Examples**

```javascript
server.use(restify.plugins.acceptParser(server.acceptable));
```

-   Throws **NotAcceptableError** 

Returns **[Function][35]** restify handler.

### authorizationParser

Parses out the `Authorization` header as best restify can.
Currently only HTTP Basic Auth and
[HTTP Signature][43]
schemes are supported.

**Parameters**

-   `options` **[Object][39]?** an optional options object that is
                                   passed to http-signature

**Examples**

Subsequent handlers will see `req.authorization`, which looks like above.

`req.username` will also be set, and defaults to 'anonymous'.  If the scheme
is unrecognized, the only thing available in `req.authorization` will be
`scheme` and `credentials` - it will be up to you to parse out the rest.


```javascript
{
  scheme: "<Basic|Signature|...>",
  credentials: "<Undecoded value of header>",
  basic: {
    username: $user
    password: $password
  }
}
```

-   Throws **InvalidArgumentError** 

Returns **[Function][35]** Handler

### dateParser

Parses out the HTTP Date header (if present) and checks for clock skew.
If the header is invalid, a `InvalidHeaderError` (`400`) is returned.
If the clock skew exceeds the specified value,
a `RequestExpiredError` (`400`) is returned.
Where expired means the request originated at a time
before (`$now - $clockSkew`).
The default clockSkew allowance is 5m (thanks
Kerberos!)

**Parameters**

-   `clockSkew` **[Number][44]** allowed clock skew in seconds. (optional, default `300`)

**Examples**

```javascript
// Allows clock skew of 1m
server.use(restify.plugins.dateParser(60));
```

-   Throws **RequestExpiredError** 
-   Throws **InvalidHeaderError** 

Returns **[Function][35]** restify handler.

### queryParser

Parses the HTTP query string (i.e., `/foo?id=bar&name=mark`).
If you use this, the parsed content will always be available in `req.query`,
additionally params are merged into `req.params`.
You can disable by passing in `mapParams: false` in the options object.

Many options correspond directly to option defined for the underlying
[`qs.parse`][45].

**Parameters**

-   `options` **[Object][39]?** an options object
    -   `options.mapParams` **[Object][39]** disable passing (optional, default `true`)
    -   `options.mapParams` **[Boolean][46]** Copies parsed query parameters
        into`req.params`. (optional, default `false`)
    -   `options.overrideParams` **[Boolean][46]** Only applies when if
        mapParams true.
        When true, will stomp on req.params field when existing value is found. (optional, default `false`)
    -   `options.allowDots` **[Boolean][46]** Transform `?foo.bar=baz` to a
        nested object: `{foo: {bar: 'baz'}}`. (optional, default `false`)
    -   `options.arrayLimit` **[Number][44]** Only transform `?a[$index]=b`
        to an array if `$index` is less than `arrayLimit`. (optional, default `20`)
    -   `options.depth` **[Number][44]** The depth limit for parsing
        nested objects, e.g. `?a[b][c][d][e][f][g][h][i]=j`. (optional, default `5`)
    -   `options.parameterLimit` **[Number][44]** Maximum number of query
        params parsed. Additional params are silently dropped. (optional, default `1000`)
    -   `options.parseArrays` **[Boolean][46]** Whether to parse
        `?a[]=b&a[1]=c` to an array, e.g. `{a: ['b', 'c']}`. (optional, default `true`)
    -   `options.plainObjects` **[Boolean][46]** Whether `req.query` is a
        "plain" object -- does not inherit from `Object`.
        This can be used to allow query params whose names collide with Object
        methods, e.g. `?hasOwnProperty=blah`. (optional, default `false`)
    -   `options.strictNullHandling` **[Boolean][46]** If true, `?a&b=`
        results in `{a: null, b: ''}`. Otherwise, `{a: '', b: ''}`. (optional, default `false`)

**Examples**

```javascript
server.use(restify.plugins.queryParser({ mapParams: false }));
```

Returns **[Function][35]** Handler

### jsonp

Parses the jsonp callback out of the request.
Supports checking the query string for `callback` or `jsonp` and ensuring
that the content-type is appropriately set if JSONP params are in place.
There is also a default `application/javascript` formatter to handle this.

You _should_ set the `queryParser` plugin to run before this, but if you
don't this plugin will still parse the query string properly.

**Examples**

```javascript
var server = restify.createServer();
server.use(restify.plugins.jsonp());
```

Returns **[Function][35]** Handler

### bodyParser

Blocks your chain on reading and parsing the HTTP request body.  Switches on
`Content-Type` and does the appropriate logic.  `application/json`,
`application/x-www-form-urlencoded` and `multipart/form-data` are currently
supported.

Parses `POST` bodies to `req.body`. automatically uses one of the following
parsers based on content type:

-   `urlEncodedBodyParser(options)` - parses url encoded form bodies
-   `jsonBodyParser(options)` - parses JSON POST bodies
-   `multipartBodyParser(options)` - parses multipart form bodies

All bodyParsers support the following options:

-   `options.mapParams` - default false. copies parsed post body values onto
    req.params
-   `options.overrideParams` - default false. only applies when if
    mapParams true. when true, will stomp on req.params value when
    existing value is found.

**Parameters**

-   `options` **[Object][39]?** an option object
    -   `options.maxBodySize` **[Number][44]?** The maximum size in bytes allowed in
        the HTTP body. Useful for limiting clients from hogging server memory.
    -   `options.mapParams` **[Boolean][46]?** if `req.params` should be filled with
        parsed parameters from HTTP body.
    -   `options.mapFiles` **[Boolean][46]?** if `req.params` should be filled with
        the contents of files sent through a multipart request.
        [formidable][47] is used internally
        for parsing, and a file is denoted as a multipart part with the `filename`
        option set in its `Content-Disposition`. This will only be performed if
        `mapParams` is true.
    -   `options.overrideParams` **[Boolean][46]?** if an entry in `req.params`
        should be overwritten by the value in the body if the names are the same.
        For instance, if you have the route `/:someval`,
        and someone posts an `x-www-form-urlencoded`
        Content-Type with the body `someval=happy` to `/sad`, the value will be
        `happy` if `overrideParams` is `true`, `sad` otherwise.
    -   `options.multipartHandler` **[Function][35]?** a callback to handle any
        multipart part which is not a file.
        If this is omitted, the default handler is invoked which may
        or may not map the parts into `req.params`, depending on
        the `mapParams`-option.
    -   `options.multipartFileHandler` **[Function][35]?** a callback to handle any
        multipart file.
        It will be a file if the part has a `Content-Disposition` with the
        `filename` parameter set. This typically happens when a browser sends a
        form and there is a parameter similar to `<input type="file" />`.
        If this is not provided, the default behaviour is to map the contents
        into `req.params`.
    -   `options.keepExtensions` **[Boolean][46]?** if you want the uploaded
        files to include the extensions of the original files
        (multipart uploads only).
        Does nothing if `multipartFileHandler` is defined.
    -   `options.uploadDir` **[String][41]?** Where uploaded files are
        intermediately stored during transfer before the contents is mapped
        into `req.params`.
        Does nothing if `multipartFileHandler` is defined.
    -   `options.multiples` **[Boolean][46]?** if you want to support html5 multiple
        attribute in upload fields.
    -   `options.hash` **[String][41]?** If you want checksums calculated for
        incoming files, set this to either `sha1` or `md5`.
    -   `options.rejectUnknown` **[Boolean][46]?** Set to `true` if you want to end
        the request with a `UnsupportedMediaTypeError` when none of
        the supported content types was given.
    -   `options.requestBodyOnGet` **[Boolean][46]**  Parse body of a GET
        request. (optional, default `false`)
    -   `options.reviver` **[Function][35]?** `jsonParser` only. If a function,
        this prescribes how the value originally produced by parsing is transformed,
        before being returned. For more information check out
        `JSON.parse(text[, reviver])`.
    -   `options.maxFieldsSize` **[Number][44]** `multipartParser`
        only.
        Limits the amount of memory all fields together (except files)
        can allocate in bytes.
        The default size is `2 * 1024 * 1024` bytes _(2MB)_. (optional, default `2*1024*1024`)

**Examples**

```javascript
server.use(restify.plugins.bodyParser({
    maxBodySize: 0,
    mapParams: true,
    mapFiles: false,
    overrideParams: false,
    multipartHandler: function(part) {
        part.on('data', function(data) {
          // do something with the multipart data
        });
    },
   multipartFileHandler: function(part) {
        part.on('data', function(data) {
          // do something with the multipart file data
        });
    },
    keepExtensions: false,
    uploadDir: os.tmpdir(),
    multiples: true,
    hash: 'sha1',
    rejectUnknown: true,
    requestBodyOnGet: false,
    reviver: undefined,
    maxFieldsSize: 2 * 1024 * 1024
 }));
```

-   Throws **UnsupportedMediaTypeError** 

Returns **[Function][35]** Handler

### requestLogger

Sets up a child [bunyan][48] logger with
the current request id filled in, along with any other parameters you define.

You can pass in no options to this, in which case only the request id will be
appended, and no serializers appended (this is also the most performant); the
logger created at server creation time will be used as the parent logger.
This logger can be used normally, with [req.log][49].

This plugin does _not_ log each individual request. Use the Audit Logging
plugin or a custom middleware for that use.

**Parameters**

-   `options` **[Object][39]?** an options object
    -   `options.headers` **[Array][40]?** A list of headers to transfer from
                                         the request to top level props on the log.

**Examples**

```javascript
server.use(restify.plugins.requestLogger({
    properties: {
        foo: 'bar'
    },
    serializers: {...}
}));
```

Returns **[Function][35]** Handler

### gzipResponse

If the client sends an `accept-encoding: gzip` header (or one with an
appropriate q-val), then the server will automatically gzip all
response data.
Note that only `gzip` is supported, as this is most widely supported by
clients in the wild.
This plugin will overwrite some of the internal streams, so any
calls to `res.send`, `res.write`, etc., will be compressed.  A side effect is
that the `content-length` header cannot be known, and so
`transfer-encoding: chunked` will _always_ be set when this is in effect.
This plugin has no impact if the client does not send
`accept-encoding: gzip`.

[https://github.com/restify/node-restify/issues/284][50]

**Parameters**

-   `opts` **[Object][39]?** an options object, see: zlib.createGzip

**Examples**

```javascript
server.use(restify.plugins.gzipResponse());
```

Returns **[Function][35]** Handler

### serveStatic

Serves static files.

**Parameters**

-   `options` **[Object][39]** an options object

**Examples**

The serveStatic module is different than most of the other plugins, in that
it is expected that you are going to map it to a route, as below:


```javascript
server.get('/docs/current/*', restify.plugins.serveStatic({
  directory: './documentation/v1',
  default: 'index.html'
}));
```

The above `route` and `directory` combination will serve a file located in
`./documentation/v1/docs/current/index.html` when you attempt to hit
`http://localhost:8080/docs/current/`. If you want the serveStatic module to
serve files directly from the `/documentation/v1` directory
(and not append the request path `/docs/current/`),
you can set the `appendRequestPath` option to `false`, and the served file
would be `./documentation/v1/index.html`, in the previous example.

The plugin will enforce that all files under `directory` are served.
The `directory` served is relative to the process working directory.
You can also provide a `default` parameter such as index.html for any
directory that lacks a direct file match.
You can specify additional restrictions by passing in a `match` parameter,
which is just a `RegExp` to check against the requested file name.
Additionally, you may set the `charSet` parameter, which will append a
character set to the content-type detected by the plugin.
For example, `charSet: 'utf-8'` will result in HTML being served with a
`Content-Type` of `text/html; charset=utf-8`.
Lastly, you can pass in a `maxAge` numeric, which will set the
`Cache-Control` header. Default is `3600` (1 hour).

An additional option for serving a static file is to pass `file` in to the
serveStatic method as an option. The following will serve index.html from
the documentation/v1/ directory anytime a client requests `/home/`.


```javascript
server.get('/home/*', restify.plugins.serveStatic({
  directory: './documentation/v1',
  file: 'index.html'
}));
// or
server.get('/home/([a-z]+[.]html)', restify.plugins.serveStatic({
  directory: './documentation/v1',
  file: 'index.html'
}));
```

-   Throws **MethodNotAllowedError** \|
-   Throws **NotAuthorizedError** 
-   Throws **ResourceNotFoundError** 

Returns **[Function][35]** Handler

### serveStaticFiles

Serves static files, with API similar to expressjs

**Parameters**

-   `directory` **[String][41]** the directory to serve files from
-   `opts` **[Object][39]** an options object, which is optional
    -   `opts.maxAge` **[Number][44]** specify max age in millisecs (optional, default `0`)
    -   `opts.etag` **[Boolean][46]** enable/disable etag, default = true (optional, default `true`)
    -   `opts.setHeaders` **[Function][35]?** set custom headers for the Files
        (synchronously), The function is called as `fn(res, path, stat)`,
        where the arguments are:
             `res` the response object
             `path` the file path that is being sent
             `stat` the stat object of the file that is being sent

**Examples**

The serveStaticFiles plugin allows you to map a GET route to a
directory on the disk


```javascript
server.get('/public/*', // don't forget the `/*`
     restify.plugins.serveStaticFiles('./documentation/v1')
);
```

The GET `route` and `directory` combination will serve a file
located in `./documentation/v1/index.html` when you attempt to hit
`http://localhost:8080/public/index.html`

The plugin uses [send][51] under the hood
which is also used by `expressjs` to serve static files. Most of the options
that work with `send` will work with this plugin.

The default file the plugin looks for is `index.html`


```javascript
server.get('/public/*',
     restify.plugins.serveStaticFiles('./documentation/v1', {
     maxAge: 3600000, // this is in millisecs
     etag: false,
     setHeaders: function setCustomHeaders(response, requestedPath, stat) {
             response.setHeader('restify-plugin-x', 'awesome');
         }
     })
);
```

-   Throws **MethodNotAllowedError** 
-   Throws **NotAuthorizedError** 
-   Throws **ResourceNotFoundError** 

Returns **[Function][35]** Handler

### throttle

Creates an API rate limiter that can be plugged into the standard
restify request handling pipeline.

`restify` ships with a fairly comprehensive implementation of
[Token bucket][52], with the ability
to throttle on IP (or x-forwarded-for) and username (from `req.username`).
You define "global" request rate and burst rate, and you can define
overrides for specific keys.
Note that you can always place this on per-URL routes to enable
different request rates to different resources (if for example, one route,
like `/my/slow/database` is much easier to overwhlem
than `/my/fast/memcache`).

If a client has consumed all of their available rate/burst, an HTTP response
code of `429`
[Too Many Requests][53]
is returned.

This throttle gives you three options on which to throttle:
username, IP address and 'X-Forwarded-For'. IP/XFF is a /32 match,
so keep that in mind if using it.  Username takes the user specified
on req.username (which gets automagically set for supported Authorization
types; otherwise set it yourself with a filter that runs before this).

In both cases, you can set a `burst` and a `rate` (in requests/seconds),
as an integer/float.  Those really translate to the `TokenBucket`
algorithm, so read up on that (or see the comments above...).

In either case, the top level options burst/rate set a blanket throttling
rate, and then you can pass in an `overrides` object with rates for
specific users/IPs.  You should use overrides sparingly, as we make a new
TokenBucket to track each.

On the `options` object ip and username are treated as an XOR.

**Parameters**

-   `options` **[Object][39]** required options with:
    -   `options.burst` **[Number][44]** burst
    -   `options.rate` **[Number][44]** rate
    -   `options.ip` **[Boolean][46]?** ip
    -   `options.username` **[Boolean][46]?** username
    -   `options.xff` **[Boolean][46]?** xff
    -   `options.setHeaders` **[Boolean][46]** Set response headers for rate,
                                      limit (burst) and remaining. (optional, default `false`)
    -   `options.overrides` **[Object][39]?** overrides
    -   `options.tokensTable` **[Object][39]** a storage engine this plugin will
                                     use to store throttling keys -> bucket mappings.
                                     If you don't specify this, the default is to
                                     use an in-memory O(1) LRU, with 10k distinct
                                     keys.  Any implementation just needs to support
                                     put/get.
    -   `options.maxKeys` **[Number][44]** If using the default
                                     implementation, you can specify how large you
                                     want the table to be. (optional, default `10000`)

**Examples**

An example options object with overrides:


```javascript
{
  burst: 10,  // Max 10 concurrent requests (if tokens)
  rate: 0.5,  // Steady state: 1 request / 2 seconds
  ip: true,   // throttle per IP
  overrides: {
    '192.168.1.1': {
      burst: 0,
      rate: 0    // unlimited
  }
}
```

-   Throws **TooManyRequestsError** 

Returns **[Function][35]** Handler

### requestExpiry

Request Expiry can be used to throttle requests that have already exceeded
their client timeouts. Requests can be sent with a configurable client
timeout header, e.g. 'x-request-expiry-time', which gives in absolute ms
since epoch, when this request will be timed out by the client.

This plugin will throttle all incoming requests via a 504 where
'x-request-expiry-time' less than Date.now() -- since these incoming requests
have already been timed out by the client. This prevents the server from
processing unnecessary requests.

Request expiry will use headers to tell if the incoming request has expired.
There are two options for this plugin:
 1\. Absolute Time
    _ Time in Milliseconds since Epoch when this request should be
    considered expired
 2\. Timeout
    _ The request start time is supplied
    _ A timeout, in milliseconds, is given
    _ The timeout is added to the request start time to arrive at the
      absolute time in which the request is considered expired

#### Using an external storage mechanism for key/bucket mappings.

By default, the restify throttling plugin uses an in-memory LRU to store
mappings between throttling keys (i.e., IP address) to the actual bucket that
key is consuming.  If this suits you, you can tune the maximum number of keys
to store in memory with `options.maxKeys`; the default is 10000.

In some circumstances, you want to offload this into a shared system, such as
Redis, if you have a fleet of API servers and you're not getting steady
and/or uniform request distribution.  To enable this, you can pass in
`options.tokensTable`, which is simply any Object that supports `put` and
`get` with a `String` key, and an `Object` value.

**Parameters**

-   `opts` **[Object][39]** an options object
    -   `opts.absoluteHeader` **[String][41]?** The header key to be used for
                                          the expiry time of each request.
    -   `opts.startHeader` **[String][41]** The header key for the start time
                                          of the request.
    -   `opts.timeoutHeader` **[String][41]** The header key for the time in
                                          milliseconds that should ellapse before
                                          the request is considered expired.

**Examples**

The only option provided is `header` which is the request header used
to specify the client timeout.


```javascript
server.use(restify.plugins.requestExpiry({
    header: 'x-request-expiry-time'
});
```

Returns **[Function][35]** Handler

### inflightRequestThrottle

The `inflightRequestThrottle` module allows you to specify an upper limit to
the maximum number of inflight requests your server is able to handle. This
is a simple heuristic for protecting against event loop contention between
requests causing unacceptable latencies.

The custom error is optional, and allows you to specify your own response
and status code when rejecting incoming requests due to too many inflight
requests. It defaults to `503 ServiceUnavailableError`.

This plugin should be registered as early as possibly in the middleware stack
using `pre` to avoid performing unnecessary work.

**Parameters**

-   `opts` **[Object][39]** configure this plugin
    -   `opts.limit` **[Number][44]** maximum number of inflight requests the server
           will handle before returning an error
    -   `opts.err` **[Error][54]** A restify error used as a response when the
           inflight request limit is exceeded
    -   `opts.server` **[Function][35]** the instance of the restify server this
           plugin will throttle.

**Examples**

```javascript
var errors = require('restify-errors');
var restify = require('restify');

var server = restify.createServer();
const options = { limit: 600, server: server };
options.res = new errors.InternalServerError();
server.pre(restify.plugins.inflightRequestThrottle(options));
```

Returns **[Function][35]** middleware to be registered on server.pre

### cpuUsageThrottle

cpuUsageThrottle is a middleware that rejects a variable number of requests
(between 0% and 100%) based on a historical view of CPU utilization of a
Node.js process. Essentially, this plugin allows you to define what
constitutes a saturated Node.js process via CPU utilization and it will
handle dropping a % of requests based on that definiton. This is useful when
you would like to keep CPU bound tasks from piling up causing an increased
per-request latency.

The algorithm asks you for a maximum CPU utilization rate, which it uses to
determine at what point it should be rejecting 100% of traffic. For a normal
Node.js service, this is 1 since Node is single threaded. It uses this,
paired with a limit that you provide to determine the total % of traffic it
should be rejecting. For example, if you specify a limit of .5 and a max of
1, and the current EWMA (next paragraph) value reads .75, this plugin will
reject approximately 50% of all requests.

When looking at the process' CPU usage, this algorithm will take a load
average over a user specified interval. example, if given an interval of
250ms, this plugin will attempt to record the average CPU utilization over
250ms intervals. Due to contention for resources, the duration of each
average may be wider or narrower than 250ms. To compensate for this, we use
an exponentially weighted moving average. The EWMA algorithm is provided by
the ewma module. The parameter for configuring the EWMA is halfLife. This
value controls how quickly each load average measurment decays to half it's
value when being represented in the current average. For example, if you
have an interval of 250, and a halfLife of 250, you will take the previous
ewma value multiplied by 0.5 and add it to the new CPU utilization average
measurement multiplied by 0.5. The previous value and the new measurement
would each represent 50% of the new value. A good way of thinking about the
halfLife is in terms of how responsive this plugin will be to spikes in CPU
utilization. The higher the halfLife, the longer CPU utilization will have
to remain above your defined limit before this plugin begins rejecting
requests and, converserly, the longer it will have to drop below your limit
before the plugin begins accepting requests again. This is a knob you will
want to with play when trying to determine the ideal value for your use
case.

For a better understanding of the EWMA algorithn, refer to the documentation
for the ewma module.

**Parameters**

-   `opts` **[Object][39]** Configure this plugin.
    -   `opts.limit` **[Number][44]?** The point at which restify will begin
           rejecting a % of all requests at the front door.
           This value is a percentage.
           For example 0.8 === 80% average CPU utilization. Defaults to 0.75.
    -   `opts.max` **[Number][44]?** The point at which restify will reject 100% of
           all requests at the front door. This is used in conjunction with limit to
           determine what % of traffic restify needs to reject when attempting to
           bring the average load back to the user requested values. Since Node.js is
           single threaded, the default for this is 1. In some rare cases, a Node.js
           process can exceed 100% CPU usage and you will want to update this value.
    -   `opts.interval` **[Number][44]?** How frequently we calculate the average CPU
           utilization. When we calculate an average CPU utilization, we calculate it
           over this interval, and this drives whether or not we should be shedding
           load. This can be thought of as a "resolution" where the lower this value,
           the higher the resolution our load average will be and the more frequently
           we will recalculate the % of traffic we should be shedding. This check
           is rather lightweight, while the default is 250ms, you should be able to
           decrease this value without seeing a significant impact to performance.
    -   `opts.halfLife` **[Number][44]?** When we sample the CPU usage on an
           interval, we create a series of data points.
           We take these points and calculate a
           moving average. The halfLife indicates how quickly a point "decays" to
           half it's value in the moving average. The lower the halfLife, the more
           impact newer data points have on the average. If you want to be extremely
           responsive to spikes in CPU usage, set this to a lower value. If you want
           your process to put more emphasis on recent historical CPU usage when
           determininng whether it should shed load, set this to a higher value. The
           unit is in ms. Defaults to 250.

**Examples**

```javascript
var restify = require('restify');

var server = restify.createServer();
const options = {
  limit: .75,
  max: 1,
  interval: 250,
  halfLife: 500,
}

server.pre(restify.plugins.cpuUsageThrottle(options));
```

You can also update the plugin during runtime using the `.update()` function.
This function accepts the same `opts` object as a constructor.


```javascript
var plugin = restify.plugins.cpuUsageThrottle(options);
server.pre(plugin);

plugin.update({ limit: .4, halfLife: 5000 });
```

Returns **[Function][35]** middleware to be registered on server.pre

### conditionalHandler

Runs first handler that matches to the condition

**Parameters**

-   `candidates` **([Object][39] \| [Array][40]&lt;[Object][39]>)** candidates
    -   `candidates.handler` **([Function][35] \| [Array][40]&lt;[Function][35]>)** handler(s)
    -   `candidates.version` **([String][41] \| [Array][40]&lt;[String][41]>)?** '1.1.0', ['1.1.0', '1.2.0']
    -   `candidates.contentType` **[String][41]?** accepted content type, '\*\\/json'

**Examples**

```javascript
server.use(restify.plugins.conditionalHandler({
   contentType: 'application/json',
   version: '1.0.0',
   handler: function (req, res, next) {
       next();
   })
});

server.get('/hello/:name', restify.plugins.conditionalHandler([
  {
     version: '1.0.0',
     handler: function(req, res, next) { res.send('1.x'); }
  },
  {
     version: ['1.5.0', '2.0.0'],
     handler: function(req, res, next) { res.send('1.5.x, 2.x'); }
  },
  {
     version: '3.0.0',
     contentType: ['text/html', 'text/html']
     handler: function(req, res, next) { res.send('3.x, text'); }
  },
  {
     version: '3.0.0',
     contentType: 'application/json'
     handler: function(req, res, next) { res.send('3.x, json'); }
  },
  // Array of handlers
  {
     version: '4.0.0',
     handler: [
         function(req, res, next) { next(); },
         function(req, res, next) { next(); },
         function(req, res, next) { res.send('4.x') }
     ]
  },
]);
// 'accept-version': '^1.1.0' => 1.5.x, 2.x'
// 'accept-version': '3.x', accept: 'application/json' => '3.x, json'
```

-   Throws **InvalidVersionError** 
-   Throws **UnsupportedMediaTypeError** 

Returns **[Function][35]** Handler

### conditionalRequest

Returns a set of plugins that will compare an already set `ETag` header with
the client's `If-Match` and `If-None-Match` header, and an already set
Last-Modified header with the client's `If-Modified-Since` and
`If-Unmodified-Since` header.

You can use this handler to let clients do nice HTTP semantics with the
"match" headers.  Specifically, with this plugin in place, you would set
`res.etag=$yourhashhere`, and then this plugin will do one of:

-   return `304` (Not Modified) [and stop the handler chain]
-   return `412` (Precondition Failed) [and stop the handler chain]
-   Allow the request to go through the handler chain.

The specific headers this plugin looks at are:

-   `Last-Modified`
-   `If-Match`
-   `If-None-Match`
-   `If-Modified-Since`
-   `If-Unmodified-Since`

**Examples**

```javascript
server.use(restify.plugins.conditionalRequest());
```

```javascript
server.use(function setETag(req, res, next) {
  res.header('ETag', 'myETag');
  res.header('Last-Modified', new Date());
});

server.use(restify.plugins.conditionalRequest());

server.get('/hello/:name', function(req, res, next) {
  res.send('hello ' + req.params.name);
});
```

-   Throws **BadRequestError** 
-   Throws **PreconditionFailedError** 

Returns **[Array][40]&lt;[Function][35]>** Handlers

### auditLogger

**Parameters**

-   `opts` **[Object][39]** The options object.
    -   `opts.log` **[Object][39]** The logger.
    -   `opts.event` **[String][41]** The event from the server which initiates the
        log, one of 'pre', 'routed', or 'after'
    -   `opts.context` **[Function][35]?** The optional context function of signature
        f(req, res, route, err).  Invoked each time an audit log is generated. This
        function can return an object that customizes the format of anything off the
        req, res, route, and err objects. The output of this function will be
        available on the `context` key in the audit object.
    -   `opts.server` **[Object][39]?** The restify server, used to emit
        the audit log object programmatically
    -   `opts.printLog` **[boolean][46]** Whether to print the log
        via the logger. (optional, default `true`)
    -   `opts.serializers` **[Object][39]?** Override the default logger serializers
        for err, req and res

**Examples**

Audit logging is a special plugin, as you don't use it with `.use()`
but with the `after` event:


```javascript
server.on('after', restify.plugins.auditLogger({
  log: bunyan.createLogger({
    name: 'audit',
    stream: process.stdout
  }),
  event: 'after',
  server: SERVER,
  logMetrics : logBuffer,
  printLog : true
}));
```

You pass in the auditor a bunyan logger, optionally server object,
Ringbuffer and a flag printLog indicate if log needs to be print out at info
level or not.  By default, without specify printLog flag, it will write out
record lookling like this:


```javascript
{
  "name": "audit",
  "hostname": "your.host.name",
  "audit": true,
  "remoteAddress": "127.0.0.1",
  "remotePort": 57692,
  "req_id": "ed634c3e-1af0-40e4-ad1e-68c2fb67c8e1",
  "req": {
    "method": "GET",
    "url": "/foo",
    "headers": {
      "authorization": "Basic YWRtaW46am95cGFzczEyMw==",
      "user-agent": "curl/7.19.7 (universal-apple-darwin10.0)
         libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3",
      "host": "localhost:8080",
      "accept": "application/json"
    },
    "httpVersion": "1.1",
    "query": {
        "foo": "bar"
    },
    "trailers": {},
    "version": "*",
    "timers": {
      "bunyan": 52,
      "saveAction": 8,
      "reqResTracker": 213,
      "addContext": 8,
      "addModels": 4,
      "resNamespaces": 5,
      "parseQueryString": 11,
      "instanceHeaders": 20,
      "xForwardedProto": 7,
      "httpsRedirector": 14,
      "readBody": 21,
      "parseBody": 6,
      "xframe": 7,
      "restifyCookieParser": 15,
      "fooHandler": 23,
      "barHandler": 14,
      "carHandler": 14
    }
  },
  "res": {
    "statusCode": 200,
    "headers": {
      "access-control-allow-origin": "*",
      "access-control-allow-headers": "Accept, Accept-Version,
         Content-Length, Content-MD5, Content-Type, Date, Api-Version",
      "access-control-expose-headers": "Api-Version, Request-Id,
         Response-Time",
      "server": "Joyent SmartDataCenter 7.0.0",
      "x-request-id": "ed634c3e-1af0-40e4-ad1e-68c2fb67c8e1",
      "access-control-allow-methods": "GET",
      "x-api-version": "1.0.0",
      "connection": "close",
      "content-length": 158,
      "content-md5": "zkiRn2/k3saflPhxXI7aXA==",
      "content-type": "application/json",
      "date": "Tue, 07 Feb 2012 20:30:31 GMT",
      "x-response-time": 1639
    },
    "trailer": false
  },
  "route": {
  "name": "GetFoo",
  "version": ["1.0.0"]
  },
  "secure": false,
  "level": 30,
  "msg": "GetFoo handled: 200",
  "time": "2012-02-07T20:30:31.896Z",
  "v": 0
}
```

The `timers` field shows the time each handler took to run in microseconds.
Restify by default will record this information for every handler for each
route. However, if you decide to include nested handlers, you can track the
timing yourself by utilizing the Request
[startHandlerTimer][55] and
[endHandlerTimer][56] API.
You can also listen to auditlog event and get same above log object when
log event emits. For example


```javascript
SERVER.on('auditlog', function (data) {
    //do some process with log
});
```

Returns **[Function][35]** Handler

### metrics

The module includes the following plugins to be used with restify's `after`
event, e.g., `server.on('after', restify.plugins.metrics());`:

A plugin that listens to the server's after event and emits information
about that request.

**Parameters**

-   `opts` **[Object][39]** an options obj
    -   `opts.server` **Server** restify server
-   `callback` **createMetrics~callback** a callback fn

**Examples**

```javascript
server.on('after', restify.plugins.metrics({ server: server },
    function (err, metrics, req, res, route) {
        // metrics is an object containing information about the request
}));
```

Returns **[Function][35]** returns a function suitable to be used
  with restify server's `after` event

## Types




### metrics~callback

Callback used by metrics plugin

Type: [Function][35]

**Parameters**

-   `err` **[Error][54]** 
-   `metrics` **[Object][39]** metrics about the request
    -   `metrics.statusCode` **[Number][44]** status code of the response. can be
          undefined in the case of an uncaughtException
    -   `metrics.method` **[String][41]** http request verb
    -   `metrics.totalLatency` **[Number][44]** latency includes both request is flushed
                                             and all handlers finished
    -   `metrics.latency` **[Number][44]** latency when request is flushed
    -   `metrics.preLatency` **([Number][44] | null)** pre handlers latency
    -   `metrics.useLatency` **([Number][44] | null)** use handlers latency
    -   `metrics.routeLatency` **([Number][44] | null)** route handlers latency
    -   `metrics.path` **[String][41]** `req.path()` value
    -   `metrics.inflightRequests` **[Number][44]** Number of inflight requests pending
          in restify.
    -   `metrics.unifinishedRequests` **[Number][44]** Same as `inflightRequests`
    -   `metrics.connectionState` **[String][41]** can be either `'close'` or
         `undefined`. If this value is set, err will be a
          corresponding `RequestCloseError`.
          If connectionState is either
          `'close'`, then the `statusCode` is not applicable since the
          connection was severed before a response was written.
-   `req` **[Request][57]** the request obj
-   `res` **[Response][58]** the response obj
-   `route` **Route** the route obj that serviced the request

## req.set

Set context value by key
Requires the context plugin.

**Parameters**

-   `key` **[String][41]** key
-   `value` **any** value

Returns **[undefined][59]** no return value

## req.get

Get context value by key.
Requires the context plugin.

**Parameters**

-   `key` **[String][41]** key

Returns **any** value stored in context

## req.getAll

Get all context
Requires the context plugin.

Returns **any** value stored in context

[1]: #usage

[2]: #serverpre-plugins

[3]: #context

[4]: #dedupeslashes

[5]: #pause

[6]: #sanitizepath

[7]: #reqidheaders

[8]: #strictqueryparams

[9]: #useragentconnection

[10]: #serveruse-plugins

[11]: #acceptparser

[12]: #authorizationparser

[13]: #dateparser

[14]: #queryparser

[15]: #jsonp

[16]: #bodyparser

[17]: #requestlogger

[18]: #gzipresponse

[19]: #servestatic

[20]: #servestaticfiles

[21]: #throttle

[22]: #requestexpiry

[23]: #using-an-external-storage-mechanism-for-keybucket-mappings

[24]: #inflightrequestthrottle

[25]: #cpuusagethrottle

[26]: #conditionalhandler

[27]: #conditionalrequest

[28]: #auditlogger

[29]: #metrics

[30]: #types

[31]: #metricscallback

[32]: #reqset

[33]: #reqget

[34]: #reqgetall

[35]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[36]: https://github.com/restify/node-restify/issues/287

[37]: https://github.com/restify/node-restify/issues/409

[38]: https://github.com/restify/node-restify/wiki/1.4-to-2.0-Migration-Tips

[39]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[40]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[41]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[42]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RegExp

[43]: https://github.com/joyent/node-http-signature

[44]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[45]: https://github.com/ljharb/qs

[46]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[47]: https://github.com/felixge/node-formidable

[48]: https://github.com/trentm/node-bunyan

[49]: #request-api

[50]: https://github.com/restify/node-restify/issues/284

[51]: https://github.com/pillarjs/send

[52]: http://en.wikipedia.org/wiki/Token_bucket

[53]: http://tools.ietf.org/html/draft-nottingham-http-new-status-03#section-4

[54]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error

[55]: #starthandlertimerhandlername

[56]: #endhandlertimerhandlername

[57]: https://developer.mozilla.org/Add-ons/SDK/High-Level_APIs/request

[58]: https://developer.mozilla.org/docs/Web/Guide/HTML/HTML5

[59]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined


================================================
FILE: docs/_api/request.md
================================================
---
title: Request API
permalink: /docs/request-api/
---

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

-   [Request][1]
    -   [accepts][2]
    -   [acceptsEncoding][3]
    -   [contentLength][4]
    -   [getContentType][5]
    -   [date][6]
    -   [href][7]
    -   [id][8]
    -   [getPath][9]
    -   [getQuery][10]
    -   [time][11]
    -   [version][12]
    -   [header][13]
    -   [trailer][14]
    -   [is][15]
    -   [isChunked][16]
    -   [isKeepAlive][17]
    -   [isSecure][18]
    -   [isUpgradeRequest][19]
    -   [isUpload][20]
    -   [toString][21]
    -   [userAgent][22]
    -   [startHandlerTimer][23]
    -   [endHandlerTimer][24]
    -   [connectionState][25]
    -   [getRoute][26]
-   [Events][27]
-   [Log][28]

## Request

**Extends http.IncomingMessage**

Wraps all of the node
[http.IncomingMessage][29]
APIs, events and properties, plus the following.

### accepts

Check if the Accept header is present, and includes the given type.
When the Accept header is not present true is returned.
Otherwise the given type is matched by an exact match, and then subtypes.

**Parameters**

-   `types` **([String][30] \| [Array][31]&lt;[String][30]>)** an array of accept type headers

**Examples**

You may pass the subtype such as html which is then converted internally
to text/html using the mime lookup table:


```javascript
// Accept: text/html
req.accepts('html');
// => true

// Accept: text/*; application/json
req.accepts('html');
req.accepts('text/html');
req.accepts('text/plain');
req.accepts('application/json');
// => true

req.accepts('image/png');
req.accepts('png');
// => false
```

Returns **[Boolean][32]** is accepteed

### acceptsEncoding

Checks if the request accepts the encoding type(s) specified.

**Parameters**

-   `types` **([String][30] \| [Array][31]&lt;[String][30]>)** an array of accept type headers

Returns **[Boolean][32]** is accepted encoding

### contentLength

Returns the value of the content-length header.

Returns **[Number][33]** 

### getContentType

Returns the value of the content-type header. If a content-type is not
set, this will return a default value of `application/octet-stream`

Returns **[String][30]** content type

### date

Returns a Date object representing when the request was setup.
Like `time()`, but returns a Date object.

Returns **[Date][34]** date when request began being processed

### href

Returns the full requested URL.

**Examples**

```javascript
// incoming request is http://localhost:3000/foo/bar?a=1
server.get('/:x/bar', function(req, res, next) {
    console.warn(req.href());
    // => /foo/bar/?a=1
});
```

Returns **[String][30]** 

### id

Returns the request id. If a `reqId` value is passed in,
this will become the request’s new id. The request id is immutable,
and can only be set once. Attempting to set the request id more than
once will cause restify to throw.

**Parameters**

-   `reqId` **[String][30]** request id

Returns **[String][30]** id

### getPath

Returns the cleaned up requested URL.

**Examples**

```javascript
// incoming request is http://localhost:3000/foo/bar?a=1
server.get('/:x/bar', function(req, res, next) {
    console.warn(req.path());
    // => /foo/bar
});
```

Returns **[String][30]** 

### getQuery

Returns the raw query string. Returns empty string
if no query string is found.

**Examples**

```javascript
// incoming request is /foo?a=1
req.getQuery();
// => 'a=1'
```

If the queryParser plugin is used, the parsed query string is
available under the req.query:


```javascript
// incoming request is /foo?a=1
server.use(restify.plugins.queryParser());
req.query;
// => { a: 1 }
```

Returns **[String][30]** query

### time

The number of ms since epoch of when this request began being processed.
Like date(), but returns a number.

Returns **[Number][33]** time when request began being processed in epoch:
                   ellapsed milliseconds since
                   January 1, 1970, 00:00:00 UTC

### version

Returns the accept-version header.

Returns **[String][30]** 

### header

Get the case-insensitive request header key,
and optionally provide a default value (express-compliant).
Returns any header off the request. also, 'correct' any
correctly spelled 'referrer' header to the actual spelling used.

**Parameters**

-   `key` **[String][30]** the key of the header
-   `defaultValue` **[String][30]?** default value if header isn't
                                      found on the req

**Examples**

```javascript
req.header('Host');
req.header('HOST');
req.header('Accept', '*\/*');
```

Returns **[String][30]** header value

### trailer

Returns any trailer header off the request. Also, 'correct' any
correctly spelled 'referrer' header to the actual spelling used.

**Parameters**

-   `name` **[String][30]** the name of the header
-   `value` **[String][30]** default value if header isn't found on the req

Returns **[String][30]** trailer value

### is

Check if the incoming request contains the `Content-Type` header field,
and if it contains the given mime type.

**Parameters**

-   `type` **[String][30]** a content-type header value

**Examples**

```javascript
// With Content-Type: text/html; charset=utf-8
req.is('html');
req.is('text/html');
// => true

// When Content-Type is application/json
req.is('json');
req.is('application/json');
// => true

req.is('html');
// => false
```

Returns **[Boolean][32]** is content-type header

### isChunked

Check if the incoming request is chunked.

Returns **[Boolean][32]** is chunked

### isKeepAlive

Check if the incoming request is kept alive.

Returns **[Boolean][32]** is keep alive

### isSecure

Check if the incoming request is encrypted.

Returns **[Boolean][32]** is secure

### isUpgradeRequest

Check if the incoming request has been upgraded.

Returns **[Boolean][32]** is upgraded

### isUpload

Check if the incoming request is an upload verb.

Returns **[Boolean][32]** is upload

### toString

toString serialization

Returns **[String][30]** serialized request

### userAgent

Returns the user-agent header.

Returns **[String][30]** user agent

### startHandlerTimer

Start the timer for a request handler.
By default, restify uses calls this automatically for all handlers
registered in your handler chain.
However, this can be called manually for nested functions inside the
handler chain to record timing information.

**Parameters**

-   `handlerName` **[String][30]** The name of the handler.

**Examples**

You must explicitly invoke
endHandlerTimer() after invoking this function. Otherwise timing
information will be inaccurate.


```javascript
server.get('/', function fooHandler(req, res, next) {
    vasync.pipeline({
        funcs: [
            function nestedHandler1(req, res, next) {
                req.startHandlerTimer('nestedHandler1');
                // do something
                req.endHandlerTimer('nestedHandler1');
                return next();
            },
            function nestedHandler1(req, res, next) {
                req.startHandlerTimer('nestedHandler2');
                // do something
                req.endHandlerTimer('nestedHandler2');
                return next();

            }...
       ]...
    }, next);
});
```

Returns **[undefined][35]** no return value

### endHandlerTimer

End the timer for a request handler.
You must invoke this function if you called `startRequestHandler` on a
handler. Otherwise the time recorded will be incorrect.

**Parameters**

-   `handlerName` **[String][30]** The name of the handler.

Returns **[undefined][35]** no return value

### connectionState

Returns the connection state of the request. Current possible values are:

-   `close` - when the request has been closed by the clien

Returns **[String][30]** connection state (`"close"`)

### getRoute

Returns the route object to which the current request was matched to.

**Examples**

Route info object structure:


```javascript
{
 path: '/ping/:name',
 method: 'GET',
 versions: [],
 name: 'getpingname'
}
```

Returns **[Object][36]** route

## Events

In additional to emitting all the events from node's
[http.Server][37],
restify servers also emit a number of additional events that make building REST
and web applications much easier.

### restifyError

This event is emitted following all error events as a generic catch all. It is
recommended to use specific error events to handle specific errors, but this
event can be useful for metrics or logging. If you use this in conjunction with
other error events, the most specific event will be fired first, followed by
this one:

```js
server.get('/', function(req, res, next) {
  return next(new InternalServerError('boom'));
});

server.on('InternalServer', function(req, res, err, callback) {
  // this will get fired first, as it's the most relevant listener
  return callback();
});

server.on('restifyError', function(req, res, err, callback) {
  // this is fired second.
  return callback();
});
```

### after

After each request has been fully serviced, an `after` event is fired. This
event can be hooked into to handle audit logs and other metrics. Note that
flushing a response does not necessarily correspond with an `after` event.
restify considers a request to be fully serviced when either:

1) The handler chain for a route has been fully completed
2) An error was returned to `next()`, and the corresponding error events have
   been fired for that error type

The signature is for the after event is as follows:

```js
function(req, res, route, error) { }
```

-   `req` - the request object
-   `res` - the response object
-   `route` - the route object that serviced the request
-   `error` - the error passed to `next()`, if applicable

Note that when the server automatically responds with a
NotFound/MethodNotAllowed/VersionNotAllowed, this event will still be fired.

### pre

Before each request has been routed, a `pre` event is fired. This event can be
hooked into handle audit logs and other metrics. Since this event fires
_before_ routing has occured, it will fire regardless of whether the route is
supported or not, e.g. requests that result in a `404`.

The signature for the `pre` event is as follows:

```js
function(req, res) {}
```

-   `req` - the request object
-   `res` - the response object

Note that when the server automatically responds with a
NotFound/MethodNotAllowed/VersionNotAllowed, this event will still be fired.

### routed

A `routed` event is fired after a request has been routed by the router, but
before handlers specific to that route has run.

The signature for the `routed` event is as follows:

```js
function(req, res, route) {}
```

-   `req` - the request object
-   `res` - the response object
-   `route` - the route object that serviced the request

Note that this event will _not_ fire if a requests comes in that are not
routable, i.e. one that would result in a `404`.

### uncaughtException

If the restify server was created with `handleUncaughtExceptions: true`,
restify will leverage [domains][38] to handle
thrown errors in the handler chain. Thrown errors are a result of an explicit
`throw` statement, or as a result of programmer errors like a typo or a null
ref. These thrown errors are caught by the domain, and will be emitted via this
event. For example:

```js
server.get('/', function(req, res, next) {
    res.send(x);  // this will cause a ReferenceError
    return next();
});

server.on('uncaughtException', function(req, res, route, err) {
    // this event will be fired, with the error object from above:
    // ReferenceError: x is not defined
});
```

If you listen to this event, you **must** send a response to the client. This
behavior is different from the standard error events. If you do not listen to
this event, restify's default behavior is to call `res.send()` with the error
that was thrown.

The signature is for the after event is as follows:

```js
function(req, res, route, error) { }
```

-   `req` - the request object
-   `res` - the response object
-   `route` - the route object that serviced the request
-   `error` - the error passed to `next()`, if applicable

### close

Emitted when the server closes.


## Log

If you are using the [RequestLogger][39] plugin, the child logger
will be available on `req.log`:

```js
function myHandler(req, res, next) {
  var log = req.log;

  log.debug({params: req.params}, 'Hello there %s', 'foo');
}
```

The child logger will inject the request's UUID in the `req._id` attribute of
each log statement. Since the logger lasts for the life of the request, you can
use this to correlate statements for an individual request across any number of
separate handlers.


[1]: #request

[2]: #accepts

[3]: #acceptsencoding

[4]: #contentlength

[5]: #getcontenttype

[6]: #date

[7]: #href

[8]: #id

[9]: #getpath

[10]: #getquery

[11]: #time

[12]: #version

[13]: #header

[14]: #trailer

[15]: #is

[16]: #ischunked

[17]: #iskeepalive

[18]: #issecure

[19]: #isupgraderequest

[20]: #isupload

[21]: #tostring

[22]: #useragent

[23]: #starthandlertimer

[24]: #endhandlertimer

[25]: #connectionstate

[26]: #getroute

[27]: #events

[28]: #log

[29]: https://nodejs.org/api/http.html

[30]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[31]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[32]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[33]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[34]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date

[35]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined

[36]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[37]: http://nodejs.org/docs/latest/api/http.html#http_class_http_server

[38]: https://nodejs.org/api/domain.html

[39]: #bundled-plugins


================================================
FILE: docs/_api/response.md
================================================
---
title: Response API
permalink: /docs/response-api/
---

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

-   [Response][1]
    -   [cache][2]
    -   [noCache][3]
    -   [charSet][4]
    -   [header][5]
    -   [json][6]
    -   [link][7]
    -   [send][8]
    -   [sendRaw][9]
    -   [set][10]
    -   [status][11]
    -   [redirect][12]
    -   [redirect][13]
    -   [redirect][14]

## Response

**Extends http.ServerResponse**

Wraps all of the node
[http.ServerResponse][15]
APIs, events and properties, plus the following.

### cache

Sets the `cache-control` header.

**Parameters**

-   `type` **[String][16]** value of the header
                                       (`"public"` or `"private"`) (optional, default `"public"`)
-   `options` **[Object][17]?** an options object
    -   `options.maxAge` **[Number][18]** max-age in seconds

Returns **[String][16]** the value set to the header

### noCache

Turns off all cache related headers.

Returns **[Response][19]** self, the response object

### charSet

Appends the provided character set to the response's `Content-Type`.

**Parameters**

-   `type` **[String][16]** char-set value

**Examples**

```javascript
res.charSet('utf-8');
```

Returns **[Response][19]** self, the response object

### header

Sets headers on the response.

**Parameters**

-   `key` **[String][16]** the name of the header
-   `value` **[String][16]** the value of the header

**Examples**

If only key is specified, return the value of the header.
If both key and value are specified, set the response header.


```javascript
res.header('Content-Length');
// => undefined

res.header('Content-Length', 123);
// => 123

res.header('Content-Length');
// => 123

res.header('foo', new Date());
// => Fri, 03 Feb 2012 20:09:58 GMT
```

`header()` can also be used to automatically chain header values
when applicable:


```javascript
res.header('x-foo', 'a');
res.header('x-foo', 'b');
// => { 'x-foo': ['a', 'b'] }
```

Returns **[Object][17]** the retrieved value or the value that was set

### json

Syntatic sugar for:

```js
res.contentType = 'json';
res.send({hello: 'world'});
```

**Parameters**

-   `code` **[Number][18]?**    http status code
-   `body` **[Object][17]?**    value to json.stringify
-   `headers` **[Object][17]?** headers to set on the response

**Examples**

```javascript
res.header('content-type', 'json');
res.send({hello: 'world'});
```

Returns **[Object][17]** the response object

### link

Sets the link header.

**Parameters**

-   `key` **[String][16]**  the link key
-   `value` **[String][16]** the link value

Returns **[String][16]** the header value set to res

### send

Sends the response object. pass through to internal `__send` that uses a
formatter based on the `content-type` header.

**Parameters**

-   `code` **[Number][18]?** http status code
-   `body` **([Object][17] \| [Buffer][20] \| [Error][21])?** the content to send
-   `headers` **[Object][17]?** any add'l headers to set

**Examples**

You can use send() to wrap up all the usual writeHead(), write(), end()
calls on the HTTP API of node.
You can pass send either a `code` and `body`, or just a body. body can be
an `Object`, a `Buffer`, or an `Error`.
When you call `send()`, restify figures out how to format the response
based on the `content-type`.


```javascript
res.send({hello: 'world'});
res.send(201, {hello: 'world'});
res.send(new BadRequestError('meh'));
```

Returns **[Object][17]** the response object

### sendRaw

Like `res.send()`, but skips formatting. This can be useful when the
payload has already been preformatted.
Sends the response object. pass through to internal `__send` that skips
formatters entirely and sends the content as is.

**Parameters**

-   `code` **[Number][18]?** http status code
-   `body` **([Object][17] \| [Buffer][20] \| [Error][21])?** the content to send
-   `headers` **[Object][17]?** any add'l headers to set

Returns **[Object][17]** the response object

### set

Sets multiple header(s) on the response.
Uses `header()` underneath the hood, enabling multi-value headers.

**Parameters**

-   `name` **([String][16] \| [Object][17])** name of the header or
                                   `Object` of headers
-   `val` **[String][16]** value of the header

**Examples**

```javascript
res.header('x-foo', 'a');
res.set({
    'x-foo', 'b',
    'content-type': 'application/json'
});
// =>
// {
//    'x-foo': [ 'a', 'b' ],
//    'content-type': 'application/json'
// }
```

Returns **[Object][17]** self, the response object

### status

Sets the http status code on the response.

**Parameters**

-   `code` **[Number][18]** http status code

**Examples**

```javascript
res.status(201);
```

Returns **[Number][18]** the status code passed in

### redirect

Redirect is sugar method for redirecting.

**Parameters**

-   `options` **[Object][17]** url or an options object to configure a redirect
    -   `options.secure` **[Boolean][22]?** whether to redirect to http or https
    -   `options.hostname` **[String][16]?** redirect location's hostname
    -   `options.pathname` **[String][16]?** redirect location's pathname
    -   `options.port` **[String][16]?** redirect location's port number
    -   `options.query` **[String][16]?** redirect location's query string
                                        parameters
    -   `options.overrideQuery` **[Boolean][22]?** if true, `options.query`
                                                 stomps over any existing query
                                                 parameters on current URL.
                                                 by default, will merge the two.
    -   `options.permanent` **[Boolean][22]?** if true, sets 301. defaults to 302.
-   `next` **[Function][23]** mandatory, to complete the response and trigger
                           audit logger.

**Examples**

```javascript
res.redirect({...}, next);
```

A convenience method for 301/302 redirects. Using this method will tell
restify to stop execution of your handler chain.
You can also use an options object. `next` is required.


```javascript
res.redirect({
  hostname: 'www.foo.com',
  pathname: '/bar',
  port: 80,                 // defaults to 80
  secure: true,             // sets https
  permanent: true,
  query: {
    a: 1
  }
}, next);  // => redirects to 301 https://www.foo.com/bar?a=1
```

Returns **[undefined][24]** 

### redirect

Redirect with code and url.

**Parameters**

-   `code` **[Number][18]** http redirect status code
-   `url` **[String][16]** redirect url
-   `next` **[Function][23]** mandatory, to complete the response and trigger
                           audit logger.

**Examples**

```javascript
res.redirect(301, 'www.foo.com', next);
```

Returns **[undefined][24]** 

### redirect

Redirect with url.

**Parameters**

-   `url` **[String][16]** redirect url
-   `next` **[Function][23]** mandatory, to complete the response and trigger
                           audit logger.

**Examples**

```javascript
res.redirect('www.foo.com', next);
res.redirect('/foo', next);
```

Returns **[undefined][24]** 

[1]: #response

[2]: #cache

[3]: #nocache

[4]: #charset

[5]: #header

[6]: #json

[7]: #link

[8]: #send

[9]: #sendraw

[10]: #set

[11]: #status

[12]: #redirect

[13]: #redirect-1

[14]: #redirect-2

[15]: https://nodejs.org/docs/latest/api/http.html

[16]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[17]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

[18]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number

[19]: #response

[20]: https://nodejs.org/api/buffer.html

[21]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error

[22]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[23]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[24]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined


================================================
FILE: docs/_api/server.md
================================================
---
title: Server API
permalink: /docs/server-api/
---

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

-   [createServer][1]
-   [Server][2]
    -   [listen][3]
    -   [close][4]
    -   [get][5]
    -   [head][6]
    -   [post][7]
    -   [put][8]
    -   [patch][9]
    -   [del][10]
    -   [opts][11]
    -   [pre][12]
    -   [use][13]
    -   [param][14]
    -   [rm][15]
    -   [address][16]
    -   [inflightRequests][17]
    -   [debugInfo][18]
    -   [toString][19]
-   [Events][20]
-   [Errors][21]
-   [Types][22]
    -   [Server~methodOpts][23]

## createServer

A restify server object is the main interface through which you will register
routes and handlers for incoming requests.

**Parameters**

-   `options` **[Object][24]?** an options object
    -   `options.name` **[String][25]** Name of the server. (optional, default `"restify"`)
    -   `options.dtrace` **[Boolean][26]** enable DTrace support (optional, default `false`)
    -   `options.router` **Router** Router (optional, default `newRouter(opts)`)
    -   `options.log` **[Object][24]** [bunyan][27] instance. (optional, default `bunyan.createLogger(options.name||"restify")`)
    -   `options.url` **[String][25]?** Once listen() is called, this will be filled
        in with where the server is running.
    -   `options.certificate` **([String][25] \| [Buffer][28])?** If you want to create an HTTPS
        server, pass in a PEM-encoded certificate and key.
    -   `options.key` **([String][25] \| [Buffer][28])?** If you want to create an HTTPS server,
        pass in a PEM-encoded certificate and key.
    -   `options.formatters` **[Object][24]?** Custom response formatters for
        `res.send()`.
    -   `options.handleUncaughtExceptions` **[Boolean][26]** When true restify
        will use a domain to catch and respond to any uncaught
        exceptions that occur in its handler stack.
        Comes with significant negative performance impact. (optional, default `false`)
    -   `options.spdy` **[Object][24]?** Any options accepted by
        [node-spdy][29].
    -   `options.http2` **[Object][24]?** Any options accepted by
        [http2.createSecureServer][30].
    -   `options.handleUpgrades` **[Boolean][26]** Hook the `upgrade` event
        from the node HTTP server, pushing `Connection: Upgrade` requests through the
         regular request handling chain. (optional, default `false`)
    -   `options.onceNext` **[Boolean][26]** Prevents calling next multiple
         times (optional, default `false`)
    -   `options.strictNext` **[Boolean][26]** Throws error when next() is
         called more than once, enabled onceNext option (optional, default `false`)
    -   `options.httpsServerOptions` **[Object][24]?** Any options accepted by
        [node-https Server][31].
        If provided the following restify server options will be ignored:
        spdy, ca, certificate, key, passphrase, rejectUnauthorized, requestCert and
        ciphers; however these can all be specified on httpsServerOptions.
    -   `options.noWriteContinue` **[Boolean][26]** prevents
         `res.writeContinue()` in `server.on('checkContinue')` when proxing (optional, default `false`)
    -   `options.ignoreTrailingSlash` **[Boolean][26]** ignore trailing slash
        on paths (optional, default `false`)
    -   `options.strictFormatters` **[Boolean][26]** enables strict formatters
        behavior: a formatter matching the response's content-type is required. If
        not found, the response's content-type is automatically set to
        'application/octet-stream'. If a formatter for that content-type is not
        found, sending the response errors. (optional, default `true`)

**Examples**

```javascript
var restify = require('restify');
var server = restify.createServer();

server.listen(8080, function () {
  console.log('ready on %s', server.url);
});
```

Returns **[Server][32]** server

## Server

Creates a new Server.

**Parameters**

-   `options` **[Object][24]** an options object
    -   `options.name` **[String][25]** Name of the server.
    -   `options.dtrace` **[Boolean][26]** enable DTrace support (optional, default `false`)
    -   `options.router` **Router** Router
    -   `options.log` **[Object][24]** [bunyan][27]
        instance.
    -   `options.url` **[String][25]?** Once listen() is called, this will be filled
        in with where the server is running.
    -   `options.certificate` **([String][25] \| [Buffer][28])?** If you want to create an HTTPS
        server, pass in a PEM-encoded certificate and key.
    -   `options.key` **([String][25] \| [Buffer][28])?** If you want to create an HTTPS server,
        pass in a PEM-encoded certificate and key.
    -   `options.formatters` **[Object][24]?** Custom response formatters for
        `res.send()`.
    -   `options.handleUncaughtExceptions` **[Boolean][26]** When true restify
        will use a domain to catch and respond to any uncaught
        exceptions that occur in its handler stack.
        Comes with significant negative performance impact.
    -   `options.spdy` **[Object][24]?** Any options accepted by
        [node-spdy][29].
    -   `options.http2` **[Object][24]?** Any options accepted by
        [http2.createSecureServer][30].
    -   `options.handleUpgrades` **[Boolean][26]** Hook the `upgrade` event
        from the node HTTP server, pushing `Connection: Upgrade` requests through the
         regular request handling chain. (optional, default `false`)
    -   `options.onceNext` **[Boolean][26]** Prevents calling next multiple
         times (optional, default `false`)
    -   `options.strictNext` **[Boolean][26]** Throws error when next() is
         called more than once, enabled onceNext option (optional, default `false`)
    -   `options.httpsServerOptions` **[Object][24]?** Any options accepted by
        [node-https Server][31].
        If provided the following restify server options will be ignored:
        spdy, ca, certificate, key, passphrase, rejectUnauthorized, requestCert and
        ciphers; however these can all be specified on httpsServerOptions.
    -   `options.noWriteContinue` **[Boolean][26]** prevents
         `res.writeContinue()` in `server.on('checkContinue')` when proxing (optional, default `false`)
    -   `options.ignoreTrailingSlash` **[Boolean][26]** ignore trailing slash
        on paths (optional, default `false`)
    -   `options.strictFormatters` **[Boolean][26]** enables strict formatters
        behavior: a formatter matching the response's content-type is required. If
        not found, the response's content-type is automatically set to
        'application/octet-stream'. If a formatter for that content-type is not
        found, sending the response errors. (optional, default `true`)

**Examples**

```javascript
var restify = require('restify');
var server = restify.createServer();

server.listen(8080, function () {
  console.log('ready on %s', server.url);
});
```

### listen

Gets the server up and listening.
Wraps node's
[listen()][33].

**Parameters**

-   `port` **[Number][34]** Port
-   `host` **[Number][34]?** Host
-   `callback` **[Function][35]?** optionally get notified when listening.

**Examples**

You can call like:


```javascript
server.listen(80)
server.listen(80, '127.0.0.1')
server.listen('/tmp/server.sock')
```

-   Throws **[TypeError][36]** 

Returns **[undefined][37]** no return value

### close

Shuts down this server, and invokes callback (optionally) when done.
Wraps node's
[close()][38].

**Parameters**

-   `callback` **[Function][35]?** callback to invoke when done

Returns **[undefined][37]** no return value

### get

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `opts` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

**Examples**

```javascript
server.get('/', function (req, res, next) {
   res.send({ hello: 'world' });
   next();
});
```

Returns **Route** the newly created route.

### head

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `opts` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

Returns **Route** the newly created route.

### post

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `post` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

Returns **Route** the newly created route.

### put

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `put` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

Returns **Route** the newly created route.

### patch

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `patch` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

Returns **Route** the newly created route.

### del

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `opts` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

Returns **Route** the newly created route.

### opts

Mounts a chain on the given path against this HTTP verb

**Parameters**

-   `opts` **[Server~methodOpts][39]** if string, the URL to handle.
                                    if options, the URL to handle, at minimum.

Returns **Route** the newly created route.

### pre

Gives you hooks to run _before_ any routes are located.  This gives you
a chance to intercept the request and change headers, etc., that routing
depends on.  Note that req.params will _not_ be set yet.

**Parameters**

-   `handler` **...([Function][35] \| [Array][40])** Allows you to add handlers that
    run for all routes. _before_ routing occurs.
    This gives you a hook to change request headers and the like if you need to.
    Note that `req.params` will be undefined, as that's filled in _after_
    routing.
    Takes a function, or an array of functions.
    variable number of nested arrays of handler functions

**Examples**

```javascript
server.pre(function(req, res, next) {
  req.headers.accept = 'application/json';
  return next();
});
```

For example, `pre()` can be used to deduplicate slashes in
URLs


```javascript
server.pre(restify.pre.dedupeSlashes());
```

Returns **[Object][24]** returns self

### use

Allows you to add in handlers that run for all routes. Note that handlers
added
via `use()` will run only after the router has found a matching route. If no
match is found, these handlers will never run. Takes a function, or an array
of functions.

You can pass in any combination of functions or array of functions.

**Parameters**

-   `handler` **...([Function][35] \| [Array][40])** A variable number of handler functions-   and/or a
        variable number of nested arrays of handler functions

Returns **[Object][24]** returns self

### param

-   **See: [http://expressjs.com/guide.html#route-param%20pre-conditions][41]**

Minimal port of the functionality offered by Express.js Route Param
Pre-conditions

This basically piggy-backs on the `server.use` method. It attaches a
new middleware function that only fires if the specified parameter exists
in req.params

Exposes an API:
  server.param("user", function (req, res, next) {
    // load the user's information here, always making sure to call next()
  });

**Parameters**

-   `name` **[String][25]** The name of the URL param to respond to
-   `fn` **[Function][35]**   The middleware function to execute

Returns **[Object][24]** returns self

### rm

Removes a route from the server.
You pass in the route 'blob' you got from a mount call.

**Parameters**

-   `routeName` **[String][25]** the route name.


-   Throws **[TypeError][36]** on bad input.

Returns **[Boolean][26]** true if route was removed, false if not.

### address

Returns the server address.
Wraps node's
[address()][42].

**Examples**

```javascript
server.address()
```

Output:


```javascript
{ address: '::', family: 'IPv6', port: 8080 }
```

Returns **[Object][24]** Address of server

### inflightRequests

Returns the number of inflight requests currently being handled by the server

Returns **[number][34]** number of inflight requests

### debugInfo

Return debug information about the server.

**Examples**

```javascript
server.getDebugInfo()
```

Output:


```javascript
{
  routes: [
    {
      name: 'get',
      method: 'get',
      input: '/',
      compiledRegex: /^[\/]*$/,
      compiledUrlParams: null,
      handlers: [Array]
     }
  ],
  server: {
    formatters: {
      'application/javascript': [Function: formatJSONP],
      'application/json': [Function: formatJSON],
      'text/plain': [Function: formatText],
      'application/octet-stream': [Function: formatBinary]
    },
    address: '::',
    port: 8080,
    inflightRequests: 0,
    pre: [],
    use: [ 'parseQueryString', '_jsonp' ],
    after: []
  }
}
```

Returns **[Object][24]** debug info

### toString

toString() the server for easy reading/output.

**Examples**

```javascript
server.toString()
```

Output:


```javascript
Accepts: application/json, text/plain, application/octet-stream,
application/javascript
Name: restify
Pre: []
Router: RestifyRouter:
	DELETE: []
	GET: [get]
	HEAD: []
	OPTIONS: []
	PATCH: []
	POST: []
	PUT: []

Routes:
	get: [parseQueryString, _jsonp, function]
Secure: false
Url: http://[::]:8080
Version:
```

Returns **[String][25]** stringified server

## Events

In additional to emitting all the events from node's
[http.Server][43],
restify servers also emit a number of additional events that make building REST
and web applications much easier.

### restifyError

This event is emitted following all error events as a generic catch all. It is
recommended to use specific error events to handle specific errors, but this
event can be useful for metrics or logging. If you use this in conjunction with
other error events, the most specific event will be fired first, followed by
this one:

```js
server.get('/', function(req, res, next) {
  return next(new InternalServerError('boom'));
});

server.on('InternalServer', function(req, res, err, callback) {
  // this will get fired first, as it's the most relevant listener
  return callback();
});

server.on('restifyError', function(req, res, err, callback) {
  // this is fired second.
  return callback();
});
```

### after

After each request has been fully serviced, an `after` event is fired. This
event can be hooked into to handle audit logs and other metrics. Note that
flushing a response does not necessarily correspond with an `after` event.
restify considers a request to be fully serviced when either:

1) The handler chain for a route has been fully completed
2) An error was returned to `next()`, and the corresponding error events have
   been fired for that error type

The signature is for the after event is as follows:

```js
function(req, res, route, error) { }
```

-   `req` - the request object
-   `res` - the response object
-   `route` - the route object that serviced the request
-   `error` - the error passed to `next()`, if applicable

Note that when the server automatically responds with a
NotFound/MethodNotAllowed/VersionNotAllowed, this event will still be fired.

### pre

Before each request has been routed, a `pre` event is fired. This event can be
hooked into handle audit logs and other metrics. Since this event fires
_before_ routing has occured, it will fire regardless of whether the route is
supported or not, e.g. requests that result in a `404`.

The signature for the `pre` event is as follows:

```js
function(req, res) {}
```

-   `req` - the request object
-   `res` - the response object

Note that when the server automatically responds with a
NotFound/MethodNotAllowed/VersionNotAllowed, this event will still be fired.

### routed

A `routed` event is fired after a request has been routed by the router, but
before handlers specific to that route has run.

The signature for the `routed` event is as follows:

```js
function(req, res, route) {}
```

-   `req` - the request object
-   `res` - the response object
-   `route` - the route object that serviced the request

Note that this event will _not_ fire if a requests comes in that are not
routable, i.e. one that would result in a `404`.

### uncaughtException

If the restify server was created with `handleUncaughtExceptions: true`,
restify will leverage [domains][44] to handle
thrown errors in the handler chain. Thrown errors are a result of an explicit
`throw` statement, or as a result of programmer errors like a typo or a null
ref. These thrown errors are caught by the domain, and will be emitted via this
event. For example:

```js
server.get('/', function(req, res, next) {
    res.send(x);  // this will cause a ReferenceError
    return next();
});

server.on('uncaughtException', function(req, res, route, err) {
    // this event will be fired, with the error object from above:
    // ReferenceError: x is not defined
});
```

If you listen to this event, you **must** send a response to the client. This
behavior is different from the standard error events. If you do not listen to
this event, restify's default behavior is to call `res.send()` with the error
that was thrown.

The signature is for the after event is as follows:

```js
function(req, res, route, error) { }
```

-   `req` - the request object
-   `res` - the response object
-   `route` - the route object that serviced the request
-   `error` - the error passed to `next()`, if applicable

### close

Emitted when the server closes.


## Errors

Restify handles errors as first class citizens. When an error object is passed
to the `next()` function, an event is emitted on the server object, and the
error object will be serialized and sent to the client. An error object is any
object that passes an `instanceof Error` check.

Before the error object is sent to the client, the server will fire an event
using the name of the error, without the `Error` part of the name. For example,
given an `InternalServerError`, the server will emit an `InternalServer` event.
This creates opportunities to do logging, metrics, or payload mutation based on
the type of error. For example:

```js
var errs = require('restify-errors');

server.get('/', function(req, res, next) {
    return next(new errs.InternalServerError('boom!'));
});

server.on('InternalServer', function(req, res, err, callback) {
    // before the response is sent, this listener will be invoked, allowing
    // opportunities to do metrics capturing or logging.
    myMetrics.capture(err);
    // invoke the callback to complete your work, and the server will send out
    // a response.
    return callback();
});
```

Inside the error event listener, it is also possible to change the serialization
method of the error if desired. To do so, simply implement a custom
`toString()` or `toJSON()`. Depending on the content-type and formatter being
used for the response, one of the two serializers will be used. For example,
given the folllwing example:

```js
server.on
Download .txt
gitextract_6dd12z3s/

├── .dir-locals.el
├── .eslintignore
├── .eslintrc.js
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1-bug-report.md
│   │   └── 2-feature-request.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── stale.yml
│   └── workflows/
│       ├── ci.yml
│       └── release-please.yml
├── .gitignore
├── .npmignore
├── .prettierignore
├── .prettierrc
├── .tern-project
├── CHANGELOG.md
├── CHANGES.md
├── CONTRIBUTING.md
├── FEATURE_REQUESTS.md
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── benchmark/
│   ├── benchmarks/
│   │   ├── middleware.js
│   │   ├── response-json.js
│   │   ├── response-text.js
│   │   └── router-heavy.js
│   ├── index.js
│   ├── lib/
│   │   ├── autocannon.js
│   │   └── bench.js
│   └── package.json
├── bin/
│   └── report-latency
├── docs/
│   ├── _api/
│   │   ├── formatters.md
│   │   ├── plugins.md
│   │   ├── request.md
│   │   ├── response.md
│   │   └── server.md
│   ├── api/
│   │   ├── formatters-usage.md
│   │   ├── plugins-usage.md
│   │   ├── request-events.md
│   │   ├── request-log.md
│   │   ├── server-errors.md
│   │   └── server-events.md
│   ├── config/
│   │   ├── formatters.yaml
│   │   ├── plugins.yaml
│   │   ├── request.yaml
│   │   └── server.yaml
│   ├── guides/
│   │   ├── 4TO5GUIDE.md
│   │   ├── 6to7guide.md
│   │   ├── 8to9guide.md
│   │   ├── client.md
│   │   ├── dtrace.md
│   │   └── server.md
│   └── index.md
├── examples/
│   ├── dtrace/
│   │   ├── demo.js
│   │   ├── handler-timing.d
│   │   └── hello.js
│   ├── example.js
│   ├── http2/
│   │   ├── http2.js
│   │   └── keys/
│   │       ├── http2-cert.pem
│   │       ├── http2-csr.pem
│   │       └── http2-key.pem
│   ├── jsonp/
│   │   └── jsonp.js
│   ├── sockio/
│   │   ├── package.json
│   │   └── sockio.js
│   ├── spdy/
│   │   ├── keys/
│   │   │   ├── spdy-cert.pem
│   │   │   ├── spdy-csr.pem
│   │   │   └── spdy-key.pem
│   │   └── spdy.js
│   └── todoapp/
│       ├── README.md
│       ├── lib/
│       │   ├── client.js
│       │   ├── index.js
│       │   └── server.js
│       ├── main.js
│       ├── package.json
│       └── test/
│           └── todo.test.js
├── lib/
│   ├── chain.js
│   ├── deprecationWarnings.js
│   ├── dtrace.js
│   ├── errorTypes.js
│   ├── formatters/
│   │   ├── binary.js
│   │   ├── index.js
│   │   ├── json.js
│   │   ├── jsonp.js
│   │   └── text.js
│   ├── helpers/
│   │   └── chainComposer.js
│   ├── http_date.js
│   ├── index.js
│   ├── plugins/
│   │   ├── accept.js
│   │   ├── audit.js
│   │   ├── authorization.js
│   │   ├── bodyParser.js
│   │   ├── bodyReader.js
│   │   ├── conditionalHandler.js
│   │   ├── conditionalRequest.js
│   │   ├── cpuUsageThrottle.js
│   │   ├── date.js
│   │   ├── fieldedTextBodyParser.js
│   │   ├── formBodyParser.js
│   │   ├── fullResponse.js
│   │   ├── gzip.js
│   │   ├── index.js
│   │   ├── inflightRequestThrottle.js
│   │   ├── jsonBodyParser.js
│   │   ├── jsonp.js
│   │   ├── metrics.js
│   │   ├── multipartBodyParser.js
│   │   ├── oauth2TokenParser.js
│   │   ├── pre/
│   │   │   ├── context.js
│   │   │   ├── dedupeSlashes.js
│   │   │   ├── pause.js
│   │   │   ├── prePath.js
│   │   │   ├── reqIdHeaders.js
│   │   │   ├── strictQueryParams.js
│   │   │   └── userAgent.js
│   │   ├── query.js
│   │   ├── requestExpiry.js
│   │   ├── requestLogger.js
│   │   ├── static.js
│   │   ├── staticFiles.js
│   │   ├── throttle.js
│   │   └── utils/
│   │       ├── hrTimeDurationInMs.js
│   │       ├── httpDate.js
│   │       ├── regex.js
│   │       └── shallowCopy.js
│   ├── request.js
│   ├── response.js
│   ├── router.js
│   ├── routerRegistryRadix.js
│   ├── server.js
│   ├── upgrade.js
│   └── utils.js
├── package.json
├── test/
│   ├── .eslintrc
│   ├── chain.test.js
│   ├── chainComposer.test.js
│   ├── formatter-optional.test.js
│   ├── formatter.test.js
│   ├── index.test.js
│   ├── keys/
│   │   ├── http2-cert.pem
│   │   ├── http2-csr.pem
│   │   └── http2-key.pem
│   ├── lib/
│   │   ├── helper.js
│   │   ├── server-withDisableUncaughtException.js
│   │   └── streamRecorder.js
│   ├── plugins/
│   │   ├── .eslintrc
│   │   ├── accept.test.js
│   │   ├── audit.test.js
│   │   ├── authorization.test.js
│   │   ├── bodyReader.test.js
│   │   ├── conditionalHandler.test.js
│   │   ├── conditionalRequest.test.js
│   │   ├── context.test.js
│   │   ├── cpuUsageThrottle.test.js
│   │   ├── dedupeSlashes.test.js
│   │   ├── fieldedTextParser.test.js
│   │   ├── files/
│   │   │   ├── data-csv.txt
│   │   │   ├── data-tsv.txt
│   │   │   ├── object-csv.json
│   │   │   └── object-tsv.json
│   │   ├── formBodyParser.test.js
│   │   ├── gzip.test.js
│   │   ├── inflightRequestThrottle.test.js
│   │   ├── jsonBodyParser.test.js
│   │   ├── metrics.test.js
│   │   ├── multipart.test.js
│   │   ├── oauth2.test.js
│   │   ├── plugins.test.js
│   │   ├── query.test.js
│   │   ├── reqIdHeaders.test.js
│   │   ├── requestExpiry.test.js
│   │   ├── static.test.js
│   │   ├── staticFiles.test.js
│   │   ├── strictQueryParams.test.js
│   │   ├── testStaticFiles/
│   │   │   ├── docs/
│   │   │   │   ├── doc.md
│   │   │   │   └── index.html
│   │   │   ├── file1.txt
│   │   │   ├── index.html
│   │   │   └── special/
│   │   │       └── $_$/
│   │   │           └── bad (file).txt
│   │   ├── throttle.test.js
│   │   ├── userAgent.test.js
│   │   └── utilsHrTimeDurationInMs.test.js
│   ├── request.test.js
│   ├── response.test.js
│   ├── router.test.js
│   ├── routerRegistryRadix.test.js
│   ├── server.test.js
│   ├── serverHttp2.test.js
│   ├── upgrade.test.js
│   └── utils.test.js
└── tools/
    ├── docsBuild.js
    └── mk/
        ├── Makefile.defs
        ├── Makefile.deps
        └── Makefile.targ
Download .txt
SYMBOL INDEX (160 symbols across 75 files)

FILE: benchmark/benchmarks/middleware.js
  function handler (line 15) | function handler(req, res, next) {

FILE: benchmark/benchmarks/router-heavy.js
  function handler (line 102) | function handler(req, res) {
  function attachRoute (line 106) | function attachRoute(parent, routeConfig) {

FILE: benchmark/index.js
  function select (line 15) | function select(callback) {

FILE: benchmark/lib/autocannon.js
  function writeResult (line 10) | function writeResult(handler, version, result) {
  function fire (line 23) | function fire(opts, handler, version, save, cb) {
  function compare (line 45) | function compare(handler) {

FILE: benchmark/lib/bench.js
  function runBenchmark (line 10) | function runBenchmark(opts, handler, version, cb) {
  function start (line 78) | function start(opts, list, index) {

FILE: examples/todoapp/lib/client.js
  function TodoClient (line 14) | function TodoClient(options) {

FILE: examples/todoapp/lib/server.js
  function formatTodo (line 39) | function formatTodo(req, res, body, cb) {
  function authenticate (line 65) | function authenticate(req, res, next) {
  function createTodo (line 104) | function createTodo(req, res, next) {
  function deleteTodo (line 138) | function deleteTodo(req, res, next) {
  function deleteAll (line 153) | function deleteAll(req, res, next) {
  function ensureTodo (line 182) | function ensureTodo(req, res, next) {
  function getTodo (line 206) | function getTodo(req, res, next) {
  function loadTodos (line 240) | function loadTodos(req, res, next) {
  function listTodos (line 269) | function listTodos(req, res, next) {
  function putTodo (line 279) | function putTodo(req, res, next) {
  function createServer (line 303) | function createServer(options) {

FILE: examples/todoapp/main.js
  function parseOptions (line 31) | function parseOptions() {
  function usage (line 77) | function usage(msg) {

FILE: lib/chain.js
  function Chain (line 31) | function Chain(options) {
  function next (line 138) | function next(err) {
  function call (line 174) | function call(handler, err, req, res, _next) {

FILE: lib/deprecationWarnings.js
  function deprecationWarnings (line 3) | function deprecationWarnings(server) {

FILE: lib/formatters/binary.js
  function formatBinary (line 17) | function formatBinary(req, res, body) {

FILE: lib/formatters/json.js
  function formatJSON (line 20) | function formatJSON(req, res, body) {

FILE: lib/formatters/jsonp.js
  function formatJSONP (line 18) | function formatJSONP(req, res, body) {

FILE: lib/formatters/text.js
  function formatText (line 17) | function formatText(req, res, body) {

FILE: lib/helpers/chainComposer.js
  function composeHandlerChain (line 20) | function composeHandlerChain(handlers, options) {

FILE: lib/index.js
  function createServer (line 73) | function createServer(options) {

FILE: lib/plugins/accept.js
  function acceptParser (line 28) | function acceptParser(accepts) {

FILE: lib/plugins/audit.js
  function getResponseHeaders (line 24) | function getResponseHeaders(res) {
  function auditLogger (line 175) | function auditLogger(opts) {

FILE: lib/plugins/authorization.js
  function parseBasic (line 26) | function parseBasic(string) {
  function parseSignature (line 65) | function parseSignature(request, options) {
  function authorizationParser (line 107) | function authorizationParser(options) {

FILE: lib/plugins/bodyParser.js
  function bodyParser (line 125) | function bodyParser(options) {

FILE: lib/plugins/bodyReader.js
  function createBodyWriter (line 23) | function createBodyWriter(req) {
  function bodyReader (line 65) | function bodyReader(options) {

FILE: lib/plugins/conditionalHandler.js
  function conditionalHandler (line 71) | function conditionalHandler(candidates) {

FILE: lib/plugins/conditionalRequest.js
  function checkIfMatch (line 20) | function checkIfMatch(req, res, next) {
  function checkIfNoneMatch (line 53) | function checkIfNoneMatch(req, res, next) {
  function checkIfModified (line 96) | function checkIfModified(req, res, next) {
  function checkIfUnmodified (line 146) | function checkIfUnmodified(req, res, next) {
  function conditionalRequest (line 211) | function conditionalRequest() {

FILE: lib/plugins/cpuUsageThrottle.js
  function cpuUsageThrottlePlugin (line 103) | function cpuUsageThrottlePlugin(opts) {

FILE: lib/plugins/date.js
  function dateParser (line 38) | function dateParser(clockSkew) {

FILE: lib/plugins/fieldedTextBodyParser.js
  function fieldedTextParser (line 21) | function fieldedTextParser(options) {

FILE: lib/plugins/formBodyParser.js
  function urlEncodedBodyParser (line 29) | function urlEncodedBodyParser(options) {

FILE: lib/plugins/fullResponse.js
  function setHeaders (line 11) | function setHeaders(req, res) {
  function fullResponse (line 63) | function fullResponse() {

FILE: lib/plugins/gzip.js
  function _writeHead (line 15) | function _writeHead(originalFunction) {
  function gzipResponse (line 50) | function gzipResponse(opts) {

FILE: lib/plugins/inflightRequestThrottle.js
  function inflightRequestThrottle (line 38) | function inflightRequestThrottle(opts) {

FILE: lib/plugins/jsonBodyParser.js
  function jsonBodyParser (line 22) | function jsonBodyParser(options) {

FILE: lib/plugins/jsonp.js
  function jsonp (line 25) | function jsonp() {

FILE: lib/plugins/metrics.js
  function createMetrics (line 48) | function createMetrics(opts, callback) {

FILE: lib/plugins/multipartBodyParser.js
  function multipartBodyParser (line 28) | function multipartBodyParser(options) {

FILE: lib/plugins/oauth2TokenParser.js
  function parseHeader (line 21) | function parseHeader(req) {
  function oauth2TokenParser (line 61) | function oauth2TokenParser(options) {

FILE: lib/plugins/pre/context.js
  function ctx (line 29) | function ctx() {

FILE: lib/plugins/pre/dedupeSlashes.js
  function createDedupeSlashes (line 19) | function createDedupeSlashes() {

FILE: lib/plugins/pre/pause.js
  function pauseStream (line 13) | function pauseStream(stream) {
  function pause (line 61) | function pause() {

FILE: lib/plugins/pre/prePath.js
  function strip (line 15) | function strip(path) {
  function sanitizePath (line 45) | function sanitizePath() {

FILE: lib/plugins/pre/reqIdHeaders.js
  function createReqIdHeaders (line 20) | function createReqIdHeaders(opts) {

FILE: lib/plugins/pre/strictQueryParams.js
  function strictQueryParams (line 29) | function strictQueryParams(options) {

FILE: lib/plugins/pre/userAgent.js
  function userAgentConnection (line 30) | function userAgentConnection(options) {

FILE: lib/plugins/query.js
  function queryParser (line 46) | function queryParser(options) {

FILE: lib/plugins/requestExpiry.js
  function requestExpiry (line 61) | function requestExpiry(opts) {

FILE: lib/plugins/requestLogger.js
  function requestLogger (line 42) | function requestLogger(options) {

FILE: lib/plugins/static.js
  function serveStatic (line 77) | function serveStatic(options) {

FILE: lib/plugins/staticFiles.js
  function serveStaticFiles (line 62) | function serveStaticFiles(directory, opts) {

FILE: lib/plugins/throttle.js
  function xor (line 24) | function xor() {
  function TokenBucket (line 61) | function TokenBucket(options) {
  function TokenTable (line 134) | function TokenTable(options) {
  function throttle (line 245) | function throttle(options) {

FILE: lib/plugins/utils/hrTimeDurationInMs.js
  function hrTimeDurationInMs (line 14) | function hrTimeDurationInMs(startTime, endTime) {

FILE: lib/plugins/utils/shallowCopy.js
  function shallowCopy (line 13) | function shallowCopy(obj) {

FILE: lib/request.js
  function negotiator (line 25) | function negotiator(req) {
  function patch (line 51) | function patch(Request) {

FILE: lib/response.js
  function patch (line 41) | function patch(Response) {
  function flush (line 858) | function flush(res, body) {
  function formatterError (line 900) | function formatterError(res, err, msg) {

FILE: lib/router.js
  function Router (line 38) | function Router(options) {
  function pathItem (line 140) | function pathItem(match, key) {
  function queryItem (line 149) | function queryItem(key) {

FILE: lib/routerRegistryRadix.js
  function RouterRegistryRadix (line 16) | function RouterRegistryRadix(options) {

FILE: lib/server.js
  function handleWithDomain (line 42) | function handleWithDomain(req, res, onError, next) {
  function Server (line 125) | function Server(options) {
  function proxyEventWhenListenerAdded (line 327) | function proxyEventWhenListenerAdded(
  function handlersToString (line 906) | function handlersToString(arr) {
  function onReqAborted (line 1355) | function onReqAborted() {
  function onResFinish (line 1372) | function onResFinish() {
  function onResClose (line 1391) | function onResClose() {
  function argumentsToChain (line 1638) | function argumentsToChain(handlers) {
  function mergeFormatters (line 1678) | function mergeFormatters(fmt) {
  function errEvtNameFromError (line 1734) | function errEvtNameFromError(err) {
  function serverMethodFactory (line 1756) | function serverMethodFactory(method) {

FILE: lib/upgrade.js
  function InvalidUpgradeStateError (line 16) | function InvalidUpgradeStateError(msg) {
  function createServerUpgradeResponse (line 61) | function createServerUpgradeResponse(req, socket, head) {
  function ServerUpgradeResponse (line 75) | function ServerUpgradeResponse(socket, head) {
  function notImplemented (line 103) | function notImplemented(method) {

FILE: lib/utils.js
  function shallowCopy (line 13) | function shallowCopy(obj) {
  function mergeQs (line 34) | function mergeQs(obj1, obj2) {

FILE: test/lib/helper.js
  method dtrace (line 85) | get dtrace() {

FILE: test/lib/server-withDisableUncaughtException.js
  function main (line 10) | function main() {

FILE: test/lib/streamRecorder.js
  class StreamRecorder (line 5) | class StreamRecorder extends stream.Writable {
    method constructor (line 6) | constructor(options) {
    method _write (line 12) | _write(chunk, encoding, callback) {
    method flushRecords (line 18) | flushRecords() {

FILE: test/plugins/audit.test.js
  constant LOG_BUFFER (line 25) | let LOG_BUFFER;
  function assertIsAtLeastWithTolerate (line 27) | function assertIsAtLeastWithTolerate(num1, num2, tolerate, msg) {

FILE: test/plugins/bodyReader.test.js
  function listenerCount (line 292) | function listenerCount(emitter) {

FILE: test/plugins/conditionalHandler.test.js
  function handlerFactory (line 17) | function handlerFactory(response, version) {

FILE: test/plugins/cpuUsageThrottle.test.js
  function next (line 33) | function next(cont) {
  function next (line 44) | function next(cont) {

FILE: test/plugins/inflightRequestThrottle.test.js
  function fakeServer (line 9) | function fakeServer(count) {
  function send (line 22) | function send(body) {
  function next (line 28) | function next(err) {
  function trace (line 32) | function trace() {
  function send (line 45) | function send(body) {
  function next (line 48) | function next(nextErr) {
  function send (line 59) | function send() {
  function next (line 62) | function next(cont) {
  function finish (line 77) | function finish() {

FILE: test/plugins/metrics.test.js
  function adjustExpectedLatency (line 18) | function adjustExpectedLatency(expectedLatency, nbTimers) {

FILE: test/plugins/static.test.js
  function serveStaticTest (line 68) | function serveStaticTest(done, testDefault, tmpDir, regex, staticFile) {
  function testNoAppendPath (line 125) | function testNoAppendPath(done, testDefault, tmpDir, regex, staticFile) {

FILE: test/plugins/staticFiles.test.js
  function simpleTests (line 47) | function simpleTests(endpoint, filePath, contentType, done) {
  function testsWithOptions (line 143) | function testsWithOptions(endpoint, filePath, options, contentType, done) {
  function negativeTests (line 268) | function negativeTests(
  function testsWithOptions (line 371) | function testsWithOptions(endpoint, filePath, done) {

FILE: test/plugins/throttle.test.js
  function setupClientServer (line 19) | function setupClientServer(ip, throttleOptions, done) {

FILE: test/response.test.js
  function join (line 77) | function join() {
  function A (line 418) | function A(req, res, next) {
  function B (line 422) | function B(req, res, next) {
  function redirect (line 427) | function redirect(req, res, next) {
  function preRedirectHandler (line 448) | function preRedirectHandler(req, res, next) {
  function redirect (line 455) | function redirect(req, res, next) {
  function handler (line 478) | function handler(req, res, next) {

FILE: test/router.test.js
  function handler (line 33) | function handler(req, res, next) {
  function handler (line 58) | function handler(req, res, next) {
  function handler (line 98) | function handler(req, res, next) {
  function handler (line 151) | function handler(req, res, next) {
  function handler1 (line 300) | function handler1(req, res, next) {
  function handler2 (line 303) | function handler2(req, res, next) {
  function handler (line 331) | function handler(req, res, next) {
  function handler (line 354) | function handler(req, res, next) {

FILE: test/routerRegistryRadix.test.js
  function getTestRoute (line 16) | function getTestRoute(opts) {

FILE: test/server.test.js
  constant LOG_BUFFER (line 36) | let LOG_BUFFER;
  function route (line 829) | function route(req, res, next) {
  function MyCustomError (line 1048) | function MyCustomError() {}
  function getDone (line 2683) | function getDone(_, __, res) {

FILE: test/upgrade.test.js
  function finish_latch (line 32) | function finish_latch(_test, _names) {

FILE: tools/docsBuild.js
  function build (line 96) | function build(options) {
Condensed preview — 193 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,070K chars).
[
  {
    "path": ".dir-locals.el",
    "chars": 179,
    "preview": "((nil . ((indent-tabs-mode . nil)\n         (tab-width . 4)\n         (fill-column . 80)))\n (js-mode . ((js-indent-level ."
  },
  {
    "path": ".eslintignore",
    "chars": 117,
    "preview": "# node_modules ignored by default\nnode_modules/\n\n# other ignored directories\nbin/\ndeps/\ndocs/\nexamples/\ncover_html/\n\n"
  },
  {
    "path": ".eslintrc.js",
    "chars": 5279,
    "preview": "'use strict';\n\nvar OFF = 0;\nvar ERROR = 2;\n\nvar config = {\n    extends: [],\n    plugins: ['jsdoc'],\n    env: {\n        b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1-bug-report.md",
    "chars": 2677,
    "preview": "---\nname: \"\\U0001F41B Bug report\"\nabout: Create a report to help us improve\n\n---\n\n<!-- Thank you for taking the time to "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/2-feature-request.md",
    "chars": 1449,
    "preview": "---\nname: \"\\U0001F680 Feature request\"\nabout: Suggest an idea for this project\n\n---\n\n<!-- Thank you for taking the time "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1561,
    "preview": "<!--\nThank you for taking the time to open an PR for restify! If this is your first\ntime here, welcome to our community!"
  },
  {
    "path": ".github/stale.yml",
    "chars": 397,
    "preview": "daysUntilStale: 60\ndaysUntilClose: 14\nexemptLabels:\n  - Critical\n  - Serve\nstaleLabel: Stale\nmarkComment: >\n  This issue"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1046,
    "preview": "on:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\nname: ci\njobs:\n  lint:\n    name: l"
  },
  {
    "path": ".github/workflows/release-please.yml",
    "chars": 319,
    "preview": "on:\n  push:\n    branches:\n      - master\n      - 9.x\nname: release-please\njobs:\n  release-please:\n    runs-on: ubuntu-la"
  },
  {
    "path": ".gitignore",
    "chars": 217,
    "preview": "node_modules\ndocs/*.html\ndocs/pkg\nexamples/todoapp/node_modules\n*.log\n*.tar.gz\n*.tgz\nbuild\ndocs/*.json\nnbproject\ndeps/ja"
  },
  {
    "path": ".npmignore",
    "chars": 313,
    "preview": ".coverage_data\n.dir-locals.el\n.gitmodules\n.github\n.travis.yml\nMakefile\ncover_html\ndeps\ndocs\nexamples\ntest\ntools\n.vscode\n"
  },
  {
    "path": ".prettierignore",
    "chars": 11,
    "preview": "cover_html\n"
  },
  {
    "path": ".prettierrc",
    "chars": 43,
    "preview": "{\n  \"tabWidth\": 4,\n  \"singleQuote\": true\n}\n"
  },
  {
    "path": ".tern-project",
    "chars": 156,
    "preview": "{\n  \"libs\": [\n     \"ecma5\",\n     \"chai\"\n  ],\n  \"plugins\": {\n    \"node\": {},\n    \"complete_strings\": {},\n    \"doc_comment"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 36044,
    "preview": "## [9.0.0](https://www.github.com/restify/node-restify/compare/v8.6.1...v9.0.0) (2022-11-15)\n\n\n### ⚠ BREAKING CHANGES\n\n*"
  },
  {
    "path": "CHANGES.md",
    "chars": 20105,
    "preview": "# restify Changelog\n\n## 5.0.0\n - #1377 Remove async formatters\n - #1363 Honor port for `Response.prototype.redirect`\n - "
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2702,
    "preview": "# Contributing to Restify\n\nWelcome to the restify community! This document is written both for maintainers and community"
  },
  {
    "path": "FEATURE_REQUESTS.md",
    "chars": 5116,
    "preview": "Feature Requests\n================\n\nWhile the maintainers of restify work hard to provide the best possible\nframwork for "
  },
  {
    "path": "LICENSE",
    "chars": 1076,
    "preview": "Copyright (c) 2011 Mark Cavage, All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "Makefile",
    "chars": 1798,
    "preview": "#\n# Copyright (c) 2012, Joyent, Inc. All rights reserved.\n#\n# Makefile: basic Makefile for template API service\n#\n# This"
  },
  {
    "path": "README.md",
    "chars": 3835,
    "preview": "<!-- Please don't remove this: Grab your social icons from https://github.com/carlsednaoui/gitsocial -->\n\n<!-- display t"
  },
  {
    "path": "SECURITY.md",
    "chars": 231,
    "preview": "# Security Policy\n\n## Reporting a Vulnerability\n\nDo not disclose vulnerabilities in public issues. Please report vulnera"
  },
  {
    "path": "benchmark/benchmarks/middleware.js",
    "chars": 551,
    "preview": "'use strict';\n\nvar restify = process.argv.includes('version=head')\n    ? require('../../lib')\n    : require('restify');\n"
  },
  {
    "path": "benchmark/benchmarks/response-json.js",
    "chars": 394,
    "preview": "'use strict';\n\nvar restify = process.argv.includes('version=head')\n    ? require('../../lib')\n    : require('restify');\n"
  },
  {
    "path": "benchmark/benchmarks/response-text.js",
    "chars": 389,
    "preview": "'use strict';\n\nvar restify = process.argv.includes('version=head')\n    ? require('../../lib')\n    : require('restify');\n"
  },
  {
    "path": "benchmark/benchmarks/router-heavy.js",
    "chars": 3611,
    "preview": "'use strict';\n\nvar restify = process.argv.includes('version=head')\n    ? require('../../lib')\n    : require('restify');\n"
  },
  {
    "path": "benchmark/index.js",
    "chars": 3015,
    "preview": "#!/usr/bin/env node\n'use strict';\n\nvar inquirer = require('inquirer');\nvar bench = require('./lib/bench');\nvar stableVer"
  },
  {
    "path": "benchmark/lib/autocannon.js",
    "chars": 1911,
    "preview": "'use strict';\n\nvar autocannon = require('autocannon');\nvar fs = require('fs');\nvar autocannonCompare = require('autocann"
  },
  {
    "path": "benchmark/lib/bench.js",
    "chars": 3527,
    "preview": "#!/usr/bin/env node\n'use strict';\n\nvar fork = require('child_process').fork;\nvar ora = require('ora');\nvar path = requir"
  },
  {
    "path": "benchmark/package.json",
    "chars": 354,
    "preview": "{\n  \"name\": \"restify-benchmark\",\n  \"homepage\": \"http://restifyjs.com\",\n  \"description\": \"Restify benchmark\",\n  \"version\""
  },
  {
    "path": "bin/report-latency",
    "chars": 5499,
    "preview": "#!/usr/bin/env node\n// -*- mode: js -*-\n\nvar fs = require('fs');\nvar path = require('path');\nvar spawn = require('child_"
  },
  {
    "path": "docs/_api/formatters.md",
    "chars": 3095,
    "preview": "---\ntitle: Formatters API\npermalink: /docs/formatters-api/\n---\n\n<!-- Generated by documentation.js. Update this document"
  },
  {
    "path": "docs/_api/plugins.md",
    "chars": 46714,
    "preview": "---\ntitle: Plugins API\npermalink: /docs/plugins-api/\n---\n\n<!-- Generated by documentation.js. Update this documentation "
  },
  {
    "path": "docs/_api/request.md",
    "chars": 14064,
    "preview": "---\ntitle: Request API\npermalink: /docs/request-api/\n---\n\n<!-- Generated by documentation.js. Update this documentation "
  },
  {
    "path": "docs/_api/response.md",
    "chars": 8130,
    "preview": "---\ntitle: Response API\npermalink: /docs/response-api/\n---\n\n<!-- Generated by documentation.js. Update this documentatio"
  },
  {
    "path": "docs/_api/server.md",
    "chars": 25427,
    "preview": "---\ntitle: Server API\npermalink: /docs/server-api/\n---\n\n<!-- Generated by documentation.js. Update this documentation by"
  },
  {
    "path": "docs/api/formatters-usage.md",
    "chars": 518,
    "preview": "Restify comes bundled with a selection of useful formatters that prepare your\nresponses for being sent over the wire, bu"
  },
  {
    "path": "docs/api/plugins-usage.md",
    "chars": 759,
    "preview": "Restify comes bundled with a selection of useful plugins. These are accessible\noff of `restify.plugins` and `restify.pre"
  },
  {
    "path": "docs/api/request-events.md",
    "chars": 670,
    "preview": "### restifyDone\n\nAfter request has been fully serviced, an `restifyDone` event is fired.\nrestify considers a request to "
  },
  {
    "path": "docs/api/request-log.md",
    "chars": 501,
    "preview": "If you are using the [RequestLogger](#bundled-plugins) plugin, the child logger\nwill be available on `req.log`:\n\n```js\nf"
  },
  {
    "path": "docs/api/server-errors.md",
    "chars": 4855,
    "preview": "Restify handles errors as first class citizens. When an error object is passed\nto the `next()` function, an event is emi"
  },
  {
    "path": "docs/api/server-events.md",
    "chars": 4341,
    "preview": "In additional to emitting all the events from node's\n[http.Server](http://nodejs.org/docs/latest/api/http.html#http_clas"
  },
  {
    "path": "docs/config/formatters.yaml",
    "chars": 341,
    "preview": "toc:\n  - name: Usage\n    file: ../api/formatters-usage.md\n  - name: Types\n    children:\n      - formatter\n  - name: Incl"
  },
  {
    "path": "docs/config/plugins.yaml",
    "chars": 944,
    "preview": "toc:\n  - name: Usage\n    file: ../api/plugins-usage.md\n  - name: server.pre() plugins\n    description: |\n      This modu"
  },
  {
    "path": "docs/config/request.yaml",
    "chars": 114,
    "preview": "toc:\n  - Request\n  - name: Events\n    file: ../api/server-events.md\n  - name: Log\n    file: ../api/request-log.md\n"
  },
  {
    "path": "docs/config/server.yaml",
    "chars": 191,
    "preview": "toc:\n  - createServer\n  - Server\n  - name: Events\n    file: ../api/server-events.md\n  - name: Errors\n    file: ../api/se"
  },
  {
    "path": "docs/guides/4TO5GUIDE.md",
    "chars": 7514,
    "preview": "---\ntitle: restify 4.x to 5.x migration guide\npermalink: /docs/4to5/\n---\n\n\n## Introduction\n\nrestify 5.0 is finally here!"
  },
  {
    "path": "docs/guides/6to7guide.md",
    "chars": 5599,
    "preview": "---\ntitle: restify 6.x to 7.x migration guide\npermalink: /docs/6to7/\n---\n\n## Introduction\n\nrestify `7.x` comes with a co"
  },
  {
    "path": "docs/guides/8to9guide.md",
    "chars": 3566,
    "preview": "---\ntitle: restify 8.x to 9.x migration guide\npermalink: /docs/8to9/\n---\n\n## Introduction\n\nRestify `9.x` comes with `asy"
  },
  {
    "path": "docs/guides/client.md",
    "chars": 11349,
    "preview": "---\ntitle: Client Guide\npermalink: /docs/client-guide/\n---\n\nThere are actually three separate clients shipped in restify"
  },
  {
    "path": "docs/guides/dtrace.md",
    "chars": 6113,
    "preview": "---\ntitle: Dtrace\npermalink: /docs/dtrace/\n---\n\nOne of the coolest features of restify is that it automatically\ncreates "
  },
  {
    "path": "docs/guides/server.md",
    "chars": 16580,
    "preview": "# Server Guide\n\nSetting up a server is quick and easy. Here is a barebones echo server:\n\n```js\nvar restify = require('re"
  },
  {
    "path": "docs/index.md",
    "chars": 27566,
    "preview": "---\ntitle: Quick Start\npermalink: /docs/home/\nredirect_from: /docs/\n---\n\nSetting up a server is quick and easy. Here is "
  },
  {
    "path": "examples/dtrace/demo.js",
    "chars": 5814,
    "preview": "'use strict';\n\n// There's an example D script here to showcase a \"slow\" handler where it's\n// wildcard'd by the route na"
  },
  {
    "path": "examples/dtrace/handler-timing.d",
    "chars": 540,
    "preview": "#!/usr/sbin/dtrace -s\n#pragma D option quiet\n\nrestify*:::route-start\n{\n        track[arg2] = timestamp;\n}\n\n\nrestify*:::h"
  },
  {
    "path": "examples/dtrace/hello.js",
    "chars": 773,
    "preview": "var restify = require('../../lib');\n\nvar server = restify.createServer({\n    name: 'helloworld',\n    dtrace: true\n});\n\ns"
  },
  {
    "path": "examples/example.js",
    "chars": 623,
    "preview": "'use strict';\n\nvar restify = require('../lib');\nvar server = restify.createServer();\n\nserver.pre(function pre(req, res, "
  },
  {
    "path": "examples/http2/http2.js",
    "chars": 874,
    "preview": "var path = require('path');\nvar fs = require('fs');\nvar pino = require('pino');\nvar restify = require('../../lib');\n\nvar"
  },
  {
    "path": "examples/http2/keys/http2-cert.pem",
    "chars": 799,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICHzCCAYgCCQCPPSUAa8QZojANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJS\nVTETMBEGA1UECBMKU29tZS1TdGF"
  },
  {
    "path": "examples/http2/keys/http2-csr.pem",
    "chars": 624,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBkzCB/QIBADBUMQswCQYDVQQGEwJSVTETMBEGA1UECBMKU29tZS1TdGF0ZTEN\nMAsGA1UEBxMET21zazE"
  },
  {
    "path": "examples/http2/keys/http2-key.pem",
    "chars": 888,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDVufbmw+S/jrCXvQF9/Gtp2WRF3/Gnld/wcOE9J/M01y0RFiyV\ndPZ9fsOZ93nDVdNWqoaoniL"
  },
  {
    "path": "examples/jsonp/jsonp.js",
    "chars": 311,
    "preview": "var restify = require('../../lib');\n\nvar srv = restify.createServer();\nsrv.use(restify.plugins.queryParser());\nsrv.use(r"
  },
  {
    "path": "examples/sockio/package.json",
    "chars": 216,
    "preview": "{\n  \"name\": \"restify-example\",\n  \"version\": \"0.0.0\",\n  \"description\": \"Socket.io example\",\n  \"main\": \"sockio.js\",\n  \"dep"
  },
  {
    "path": "examples/sockio/sockio.js",
    "chars": 1058,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\nvar socketio = require('socket.io');\n\nvar restify = require('"
  },
  {
    "path": "examples/spdy/keys/spdy-cert.pem",
    "chars": 799,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICHzCCAYgCCQCPPSUAa8QZojANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJS\nVTETMBEGA1UECBMKU29tZS1TdGF"
  },
  {
    "path": "examples/spdy/keys/spdy-csr.pem",
    "chars": 624,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBkzCB/QIBADBUMQswCQYDVQQGEwJSVTETMBEGA1UECBMKU29tZS1TdGF0ZTEN\nMAsGA1UEBxMET21zazE"
  },
  {
    "path": "examples/spdy/keys/spdy-key.pem",
    "chars": 888,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDVufbmw+S/jrCXvQF9/Gtp2WRF3/Gnld/wcOE9J/M01y0RFiyV\ndPZ9fsOZ93nDVdNWqoaoniL"
  },
  {
    "path": "examples/spdy/spdy.js",
    "chars": 707,
    "preview": "var path = require('path');\nvar fs = require('fs');\nvar pino = require('pino');\nvar restify = require('../../lib');\n\nvar"
  },
  {
    "path": "examples/todoapp/README.md",
    "chars": 4904,
    "preview": "# tl;dr\n\nThis is a (small) sample app using a reasonable subset of restify components to\nillustrate how you go about str"
  },
  {
    "path": "examples/todoapp/lib/client.js",
    "chars": 2960,
    "preview": "// Copyright (c) 2012 Mark Cavage. All rights reserved.\n\nvar util = require('util');\n\nvar assert = require('assert-plus'"
  },
  {
    "path": "examples/todoapp/lib/index.js",
    "chars": 182,
    "preview": "// Copyright (c) 2012 Mark Cavage. All rights reserved.\n\nmodule.exports = {\n    createClient: require('./client').create"
  },
  {
    "path": "examples/todoapp/lib/server.js",
    "chars": 11254,
    "preview": "// Copyright (c) 2012 Mark Cavage. All rights reserved.\n\nvar fs = require('fs');\nvar path = require('path');\nvar util = "
  },
  {
    "path": "examples/todoapp/main.js",
    "chars": 2776,
    "preview": "// Copyright (c) 2012 Mark Cavage. All rights reserved.\n\nvar fs = require('fs');\nvar path = require('path');\n\nvar pino ="
  },
  {
    "path": "examples/todoapp/package.json",
    "chars": 764,
    "preview": "{\n        \"name\": \"restify-example\",\n        \"version\": \"0.0.0\",\n        \"description\": \"Kitchen Sink App of restify\",\n "
  },
  {
    "path": "examples/todoapp/test/todo.test.js",
    "chars": 3501,
    "preview": "// Copyright (c) 2012 Mark Cavage. All rights reserved.\n\nvar fs = require('fs');\n\nvar pino = require('pino');\nvar restif"
  },
  {
    "path": "lib/chain.js",
    "chars": 6432,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\nvar once = require('once');\nvar customErrorTypes = require('./errorT"
  },
  {
    "path": "lib/deprecationWarnings.js",
    "chars": 738,
    "preview": "'use strict';\n\nfunction deprecationWarnings(server) {\n    // deprecation for domains and next.ifError\n    if (server.han"
  },
  {
    "path": "lib/dtrace.js",
    "chars": 2141,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n///--- Globals\n\n'use strict';\n\nvar ID = 0;\nvar MAX_INT = Math"
  },
  {
    "path": "lib/errorTypes.js",
    "chars": 322,
    "preview": "'use strict';\n\nvar errors = require('restify-errors');\n\n// This allows Restify to work with restify-errors v6+\nmodule.ex"
  },
  {
    "path": "lib/formatters/binary.js",
    "chars": 551,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n///--- Exports\n\n/**\n * Binary formatter.\n *\n *"
  },
  {
    "path": "lib/formatters/index.js",
    "chars": 632,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n///--- Exports\n\n/**\n * Format a response for be"
  },
  {
    "path": "lib/formatters/json.js",
    "chars": 1073,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar errors = require('restify-errors');\n\n///--"
  },
  {
    "path": "lib/formatters/jsonp.js",
    "chars": 1135,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n///--- Exports\n\n/**\n * JSONP formatter. like J"
  },
  {
    "path": "lib/formatters/text.js",
    "chars": 922,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n/**\n * Formats the body to 'text' by invoking "
  },
  {
    "path": "lib/helpers/chainComposer.js",
    "chars": 989,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar Chain = require('../chain');\nvar _ = require('lodash');\n\nmodule.expor"
  },
  {
    "path": "lib/http_date.js",
    "chars": 428,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n/**\n * Takes an instance of a date object, for"
  },
  {
    "path": "lib/index.js",
    "chars": 4620,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar error"
  },
  {
    "path": "lib/plugins/accept.js",
    "chars": 1740,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar mime "
  },
  {
    "path": "lib/plugins/audit.js",
    "chars": 10486,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar pino "
  },
  {
    "path": "lib/plugins/authorization.js",
    "chars": 3813,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar httpSignature = require('http-signature');"
  },
  {
    "path": "lib/plugins/bodyParser.js",
    "chars": 8125,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar error"
  },
  {
    "path": "lib/plugins/bodyReader.js",
    "chars": 5380,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar crypto = require('crypto');\nvar zlib = req"
  },
  {
    "path": "lib/plugins/conditionalHandler.js",
    "chars": 5819,
    "preview": "'use strict';\n\nvar errors = require('restify-errors');\nvar _ = require('lodash');\nvar assert = require('assert-plus');\nv"
  },
  {
    "path": "lib/plugins/conditionalRequest.js",
    "chars": 5769,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar errors = require('restify-errors');\n\n///--"
  },
  {
    "path": "lib/plugins/cpuUsageThrottle.js",
    "chars": 12537,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\nvar pidusage = require('pidusage');\nvar errors = require('restify-er"
  },
  {
    "path": "lib/plugins/date.js",
    "chars": 2428,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar error"
  },
  {
    "path": "lib/plugins/fieldedTextBodyParser.js",
    "chars": 2013,
    "preview": "/**\n * Dependencies\n */\n\n'use strict';\n\nvar csv = require('csv');\nvar assert = require('assert-plus');\n\n///--- API\n\n/**\n"
  },
  {
    "path": "lib/plugins/formBodyParser.js",
    "chars": 1928,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar query"
  },
  {
    "path": "lib/plugins/fullResponse.js",
    "chars": 2116,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar crypto = require('crypto');\nvar httpDate ="
  },
  {
    "path": "lib/plugins/gzip.js",
    "chars": 2429,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar zlib = require('zlib');\n\nvar assert = requ"
  },
  {
    "path": "lib/plugins/index.js",
    "chars": 1590,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n///--- Exports\n\nmodule.exports = {\n    acceptP"
  },
  {
    "path": "lib/plugins/inflightRequestThrottle.js",
    "chars": 2864,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\nvar ServiceUnavailableError = require('restify-errors').ServiceUnava"
  },
  {
    "path": "lib/plugins/jsonBodyParser.js",
    "chars": 3020,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\nvar error"
  },
  {
    "path": "lib/plugins/jsonp.js",
    "chars": 1147,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar qs = require('qs');\n\n///--- API\n\n/**\n * Pa"
  },
  {
    "path": "lib/plugins/metrics.js",
    "chars": 5315,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\nvar hrTimeDurationInMs = require('./utils/hrTimeDurationInMs');\n\n/**"
  },
  {
    "path": "lib/plugins/multipartBodyParser.js",
    "chars": 5414,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar fs = require('fs');\n\nvar assert = require("
  },
  {
    "path": "lib/plugins/oauth2TokenParser.js",
    "chars": 2372,
    "preview": "/*\noauth2TokenParser - Parser oauth2 tokens from the authorization header\nor BODY of the request\n\nIf parsing from the BO"
  },
  {
    "path": "lib/plugins/pre/context.js",
    "chars": 2265,
    "preview": "// Copyright 2018 Restify. All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\n\n///--- API\n\n/**\n *"
  },
  {
    "path": "lib/plugins/pre/dedupeSlashes.js",
    "chars": 685,
    "preview": "'use strict';\n\n/**\n * This plugin deduplicates extra slashes found in the URL. This can help with\n * malformed URLs that"
  },
  {
    "path": "lib/plugins/pre/pause.js",
    "chars": 1637,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n///--- Helpers\n\n/**\n * @private\n * @function p"
  },
  {
    "path": "lib/plugins/pre/prePath.js",
    "chars": 1054,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n///--- Helpers\n\n/**\n * Cleans up sloppy URLs o"
  },
  {
    "path": "lib/plugins/pre/reqIdHeaders.js",
    "chars": 1151,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\n\nvar DEFAULT_HEADERS = ['request-id', 'x-request-id'];\n\n/**\n * This "
  },
  {
    "path": "lib/plugins/pre/strictQueryParams.js",
    "chars": 1581,
    "preview": "'use strict';\n\nvar BadRequestError = require('restify-errors').BadRequestError;\nvar assert = require('assert-plus');\n\n//"
  },
  {
    "path": "lib/plugins/pre/userAgent.js",
    "chars": 1712,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\n\n///--- A"
  },
  {
    "path": "lib/plugins/query.js",
    "chars": 2755,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar qs = require('qs');\nvar assert = require('"
  },
  {
    "path": "lib/plugins/requestExpiry.js",
    "chars": 5062,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\nvar GatewayTimeoutError = require('restify-errors').GatewayTimeoutEr"
  },
  {
    "path": "lib/plugins/requestLogger.js",
    "chars": 2817,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar assert = require('assert-plus');\n\nvar shal"
  },
  {
    "path": "lib/plugins/static.js",
    "chars": 7744,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar fs = require('fs');\nvar path = require('pa"
  },
  {
    "path": "lib/plugins/staticFiles.js",
    "chars": 5303,
    "preview": "'use strict';\nvar assert = require('assert-plus');\nvar errors = require('restify-errors');\nvar path = require('path');\nv"
  },
  {
    "path": "lib/plugins/throttle.js",
    "chars": 10427,
    "preview": "// Copyright 2012 Mark Cavage <mcavage@gmail.com> All rights reserved.\n\n'use strict';\n\nvar sprintf = require('util').for"
  },
  {
    "path": "lib/plugins/utils/hrTimeDurationInMs.js",
    "chars": 700,
    "preview": "'use strict';\n\nvar NS_PER_SEC = 1e9;\nvar MS_PER_NS = 1e6;\n\n/**\n* Get duration in milliseconds from two process.hrtime()\n"
  },
  {
    "path": "lib/plugins/utils/httpDate.js",
    "chars": 380,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n/**\n * Takes an instance of a date object, for"
  },
  {
    "path": "lib/plugins/utils/regex.js",
    "chars": 103,
    "preview": "'use strict';\n\nmodule.exports = {\n    jsonContentType: new RegExp('^application/[a-zA-Z.]+\\\\+json')\n};\n"
  },
  {
    "path": "lib/plugins/utils/shallowCopy.js",
    "chars": 507,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n/**\n * Return a shallow copy of the given obje"
  },
  {
    "path": "lib/request.js",
    "chars": 23530,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar url = require('url');\nvar sprintf = requir"
  },
  {
    "path": "lib/response.js",
    "chars": 28801,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar http = require('http');\nvar sprintf = requ"
  },
  {
    "path": "lib/router.js",
    "chars": 9881,
    "preview": "'use strict';\n\nvar EventEmitter = require('events').EventEmitter;\nvar util = require('util');\nvar http = require('http')"
  },
  {
    "path": "lib/routerRegistryRadix.js",
    "chars": 3222,
    "preview": "'use strict';\n\nvar assert = require('assert-plus');\nvar FindMyWay = require('find-my-way');\nvar Chain = require('./chain"
  },
  {
    "path": "lib/server.js",
    "chars": 55532,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\nvar EventEmitter = require('events').EventEmit"
  },
  {
    "path": "lib/upgrade.js",
    "chars": 8059,
    "preview": "// Copyright (c) 2013, Joyent, Inc. All rights reserved.\n\n'use strict';\n\nvar EventEmitter = require('events').EventEmitt"
  },
  {
    "path": "lib/utils.js",
    "chars": 1547,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n\n/**\n * Return a shallow copy of the given obje"
  },
  {
    "path": "package.json",
    "chars": 3356,
    "preview": "{\n  \"author\": \"Mark Cavage <mcavage@gmail.com>\",\n  \"contributors\": [\n    \"Adam Argo\",\n    \"Alex Liu\",\n    \"Alexander Ols"
  },
  {
    "path": "test/.eslintrc",
    "chars": 62,
    "preview": "{\n    \"rules\": {\n        \"handle-callback-err\": [ 0 ]\n    }\n}\n"
  },
  {
    "path": "test/chain.test.js",
    "chars": 9927,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar domain = require('domain');\nvar Chain = require('../lib/chain');\n\nif "
  },
  {
    "path": "test/chainComposer.test.js",
    "chars": 1486,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nif (require.cache[__dirname + '/lib/helper.js']) {\n    delete require.cac"
  },
  {
    "path": "test/formatter-optional.test.js",
    "chars": 2029,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar restifyClients = require('restify-clients');\n\nvar restify = require('"
  },
  {
    "path": "test/formatter.test.js",
    "chars": 8219,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n/* eslint-disable func-names */\n\nvar restifyCli"
  },
  {
    "path": "test/index.test.js",
    "chars": 522,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n/* eslint-disable func-names */\n\nvar httpDate ="
  },
  {
    "path": "test/keys/http2-cert.pem",
    "chars": 799,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICHzCCAYgCCQCPPSUAa8QZojANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJS\nVTETMBEGA1UECBMKU29tZS1TdGF"
  },
  {
    "path": "test/keys/http2-csr.pem",
    "chars": 624,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBkzCB/QIBADBUMQswCQYDVQQGEwJSVTETMBEGA1UECBMKU29tZS1TdGF0ZTEN\nMAsGA1UEBxMET21zazE"
  },
  {
    "path": "test/keys/http2-key.pem",
    "chars": 888,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDVufbmw+S/jrCXvQF9/Gtp2WRF3/Gnld/wcOE9J/M01y0RFiyV\ndPZ9fsOZ93nDVdNWqoaoniL"
  },
  {
    "path": "test/lib/helper.js",
    "chars": 2444,
    "preview": "// Copyright 2012 Mark Cavage.  All rights reserved.\n//\n// Just a simple wrapper over nodeunit's exports syntax. Also ex"
  },
  {
    "path": "test/lib/server-withDisableUncaughtException.js",
    "chars": 973,
    "preview": "// A simple node process that will start a restify server with the\n// uncaughtException handler disabled. Responds to a "
  },
  {
    "path": "test/lib/streamRecorder.js",
    "chars": 462,
    "preview": "'use strict';\n\nconst stream = require('stream');\n\nclass StreamRecorder extends stream.Writable {\n    constructor(options"
  },
  {
    "path": "test/plugins/.eslintrc",
    "chars": 41,
    "preview": "{\n    env: {\n        mocha: true\n    }\n}\n"
  },
  {
    "path": "test/plugins/accept.test.js",
    "chars": 2340,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/audit.test.js",
    "chars": 19322,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// runtime modules\nvar PassThrough = require('stream').PassThrough;\n\n// e"
  },
  {
    "path": "test/plugins/authorization.test.js",
    "chars": 1953,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/bodyReader.test.js",
    "chars": 9550,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar http = require('http');\n\n// external requires\nvar as"
  },
  {
    "path": "test/plugins/conditionalHandler.test.js",
    "chars": 20554,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar assert = require('chai').assert;\nvar restify = require('../../lib/ind"
  },
  {
    "path": "test/plugins/conditionalRequest.test.js",
    "chars": 6465,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/context.test.js",
    "chars": 2622,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/cpuUsageThrottle.test.js",
    "chars": 4624,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar assert = require('chai').assert;\nvar proxyquire = require('proxyquire"
  },
  {
    "path": "test/plugins/dedupeSlashes.test.js",
    "chars": 2059,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/fieldedTextParser.test.js",
    "chars": 5996,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar fs = require('fs');\nvar path = require('path');\n\n// "
  },
  {
    "path": "test/plugins/files/data-csv.txt",
    "chars": 58,
    "preview": "field1,field2,field3\n1,2,3\n3,2,1\n\"a\",\"b\",\"c\"\n\"\\\"c\",\"b\",\"a\""
  },
  {
    "path": "test/plugins/files/data-tsv.txt",
    "chars": 32,
    "preview": "field1\tfield2\tfield3\n1\t2\t3\n3\t2\t1"
  },
  {
    "path": "test/plugins/files/object-csv.json",
    "chars": 256,
    "preview": "[\n  { \"field1\": \"1\", \"field2\": \"2\", \"field3\": \"3\", \"index\": 0 },\n  { \"field1\": \"3\", \"field2\": \"2\", \"field3\": \"1\", \"index"
  },
  {
    "path": "test/plugins/files/object-tsv.json",
    "chars": 128,
    "preview": "[\n  { \"field1\": \"1\", \"field2\": \"2\", \"field3\": \"3\", \"index\": 0 },\n  { \"field1\": \"3\", \"field2\": \"2\", \"field3\": \"1\", \"index"
  },
  {
    "path": "test/plugins/formBodyParser.test.js",
    "chars": 8026,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar http = require('http');\n\n// external requires\nvar as"
  },
  {
    "path": "test/plugins/gzip.test.js",
    "chars": 4610,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/inflightRequestThrottle.test.js",
    "chars": 4232,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar assert = require('chai').assert;\nvar restify = require('../../lib/ind"
  },
  {
    "path": "test/plugins/jsonBodyParser.test.js",
    "chars": 14902,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar net = require('net');\nvar http = require('http');\n\n/"
  },
  {
    "path": "test/plugins/metrics.test.js",
    "chars": 11056,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\n\nvar restify = "
  },
  {
    "path": "test/plugins/multipart.test.js",
    "chars": 13221,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar http = require('http');\n\n// external requires\nvar as"
  },
  {
    "path": "test/plugins/oauth2.test.js",
    "chars": 5755,
    "preview": "// Copyright 2016 Brian Aabel, Inc.  All rights reserved.\n\n'use strict';\n/* eslint-disable func-names */\n\nvar http = req"
  },
  {
    "path": "test/plugins/plugins.test.js",
    "chars": 10818,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n/* eslint-disable func-names */\n\n// external re"
  },
  {
    "path": "test/plugins/query.test.js",
    "chars": 7601,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/reqIdHeaders.test.js",
    "chars": 4294,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external modules\nvar assert = require('chai').assert;\nvar restify = re"
  },
  {
    "path": "test/plugins/requestExpiry.test.js",
    "chars": 12479,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external modules\nvar assert = require('chai').assert;\nvar restify = re"
  },
  {
    "path": "test/plugins/static.test.js",
    "chars": 13544,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar fs = require('fs');\nvar path = require('path');\nvar "
  },
  {
    "path": "test/plugins/staticFiles.test.js",
    "chars": 12367,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar fs = require('fs');\nvar path = require('path');\nvar "
  },
  {
    "path": "test/plugins/strictQueryParams.test.js",
    "chars": 7202,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// external requires\nvar assert = require('chai').assert;\nvar restify = r"
  },
  {
    "path": "test/plugins/testStaticFiles/docs/doc.md",
    "chars": 15,
    "preview": "#This is doc.md"
  },
  {
    "path": "test/plugins/testStaticFiles/docs/index.html",
    "chars": 346,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"widt"
  },
  {
    "path": "test/plugins/testStaticFiles/file1.txt",
    "chars": 17,
    "preview": "This is file1.txt"
  },
  {
    "path": "test/plugins/testStaticFiles/index.html",
    "chars": 341,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"widt"
  },
  {
    "path": "test/plugins/testStaticFiles/special/$_$/bad (file).txt",
    "chars": 32,
    "preview": "This is a very badly named file."
  },
  {
    "path": "test/plugins/throttle.test.js",
    "chars": 7425,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n/* eslint-disable func-names */\n\nvar assert = r"
  },
  {
    "path": "test/plugins/userAgent.test.js",
    "chars": 4282,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\n// core requires\nvar child_process = require('child_process');\nvar http ="
  },
  {
    "path": "test/plugins/utilsHrTimeDurationInMs.test.js",
    "chars": 446,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar assert = require('chai').assert;\nvar hrTimeDurationInMs = require('.."
  },
  {
    "path": "test/request.test.js",
    "chars": 7270,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar restifyClients = require('restify-clients');\nvar validator = require("
  },
  {
    "path": "test/response.test.js",
    "chars": 20546,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar url = require('url');\nvar restifyClients = require('restify-clients')"
  },
  {
    "path": "test/router.test.js",
    "chars": 12866,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar restify = require('../lib');\nvar Router = require('../lib/router');\nv"
  },
  {
    "path": "test/routerRegistryRadix.test.js",
    "chars": 3423,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar RouterRegistryRadix = require('../lib/routerRegistryRadix');\nvar Chai"
  },
  {
    "path": "test/server.test.js",
    "chars": 81208,
    "preview": "// Copyright 2012 Mark Cavage, Inc.  All rights reserved.\n\n'use strict';\n/* eslint-disable func-names */\n\nconst { AsyncL"
  },
  {
    "path": "test/serverHttp2.test.js",
    "chars": 2665,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar path = require('path');\nvar fs = require('fs');\nvar http2;\n\n// http2 "
  },
  {
    "path": "test/upgrade.test.js",
    "chars": 11390,
    "preview": "// Copyright (c) 2013, Joyent, Inc. All rights reserved.\n// vim: set ts=8 sts=8 sw=8 et:\n\n'use strict';\n/* eslint-disabl"
  },
  {
    "path": "test/utils.test.js",
    "chars": 710,
    "preview": "'use strict';\n/* eslint-disable func-names */\n\nvar mergeQs = require('../lib/utils').mergeQs;\n\nif (require.cache[__dirna"
  },
  {
    "path": "tools/docsBuild.js",
    "chars": 4894,
    "preview": "'use strict';\n\nvar glob = require('glob');\nvar path = require('path');\nvar util = require('util');\nvar fs = require('fs'"
  },
  {
    "path": "tools/mk/Makefile.defs",
    "chars": 1465,
    "preview": "# -*- mode: makefile -*-\n#\n# Copyright (c) 2012, Joyent, Inc. All rights reserved.\n#\n# Makefile.defs: common defines.\n#\n"
  },
  {
    "path": "tools/mk/Makefile.deps",
    "chars": 749,
    "preview": "# -*- mode: makefile -*-\n#\n# Copyright (c) 2012, Joyent, Inc. All rights reserved.\n#\n# Makefile.deps: Makefile for inclu"
  },
  {
    "path": "tools/mk/Makefile.targ",
    "chars": 7271,
    "preview": "# -*- mode: makefile -*-\n#\n# Copyright (c) 2012, Joyent, Inc. All rights reserved.\n#\n# Makefile.targ: common targets.\n#\n"
  }
]

About this extraction

This page contains the full source code of the restify/node-restify GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 193 files (998.8 KB), approximately 249.3k tokens, and a symbol index with 160 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!