The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .github
    └── workflows
    │   └── ci.yml
├── .gitignore
├── HISTORY.md
├── LICENSE
├── README.md
├── SECURITY.md
├── index.js
├── logo
    ├── horizontal.png
    ├── icon.png
    └── vertical.png
├── package.json
└── test
    ├── app.listen.js
    ├── fqdn.js
    ├── mounting.js
    ├── server.js
    └── support
        ├── env.js
        └── rawagent.js


/.editorconfig:
--------------------------------------------------------------------------------
 1 | # http://editorconfig.org
 2 | root = true
 3 | 
 4 | [*]
 5 | charset = utf-8
 6 | insert_final_newline = true
 7 | trim_trailing_whitespace = true
 8 | 
 9 | [{*.js,*.json,*.yml}]
10 | indent_size = 2
11 | indent_style = space
12 | 


--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | .nyc_output
2 | coverage
3 | node_modules
4 | 


--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | root: true
2 | rules:
3 |   eol-last: error
4 |   indent: ["error", 2, { "SwitchCase": 1 }]
5 |   no-trailing-spaces: error
6 |   no-unused-vars: ["error", { "args": "none" }]
7 | 


--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
  1 | name: ci
  2 | 
  3 | on:
  4 | - pull_request
  5 | - push
  6 | 
  7 | jobs:
  8 |   test:
  9 |     runs-on: ubuntu-latest
 10 |     strategy:
 11 |       matrix:
 12 |         name:
 13 |         - Node.js 0.10
 14 |         - Node.js 0.12
 15 |         - io.js 1.x
 16 |         - io.js 2.x
 17 |         - io.js 3.x
 18 |         - Node.js 4.x
 19 |         - Node.js 5.x
 20 |         - Node.js 6.x
 21 |         - Node.js 7.x
 22 |         - Node.js 8.x
 23 |         - Node.js 9.x
 24 |         - Node.js 10.x
 25 |         - Node.js 11.x
 26 |         - Node.js 12.x
 27 |         - Node.js 13.x
 28 |         - Node.js 14.x
 29 |         - Node.js 15.x
 30 |         - Node.js 16.x
 31 |         - Node.js 17.x
 32 |         - Node.js 18.x
 33 |         - Node.js 20.x
 34 |         - Node.js 21.x
 35 | 
 36 |         include:
 37 |         - name: Node.js 0.10
 38 |           node-version: "0.10"
 39 |           npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0
 40 | 
 41 |         - name: Node.js 0.12
 42 |           node-version: "0.12"
 43 |           npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0
 44 | 
 45 |         - name: io.js 1.x
 46 |           node-version: "1.8"
 47 |           npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0
 48 | 
 49 |         - name: io.js 2.x
 50 |           node-version: "2.5"
 51 |           npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0
 52 | 
 53 |         - name: io.js 3.x
 54 |           node-version: "3.3"
 55 |           npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0
 56 | 
 57 |         - name: Node.js 4.x
 58 |           node-version: "4.9"
 59 |           npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
 60 | 
 61 |         - name: Node.js 5.x
 62 |           node-version: "5.12"
 63 |           npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
 64 | 
 65 |         - name: Node.js 6.x
 66 |           node-version: "6.17"
 67 |           npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6
 68 | 
 69 |         - name: Node.js 7.x
 70 |           node-version: "7.10"
 71 |           npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6
 72 | 
 73 |         - name: Node.js 8.x
 74 |           node-version: "8.17"
 75 |           npm-i: mocha@7.2.0 nyc@14.1.1
 76 | 
 77 |         - name: Node.js 9.x
 78 |           node-version: "9.11"
 79 |           npm-i: mocha@7.2.0 nyc@14.1.1
 80 | 
 81 |         - name: Node.js 10.x
 82 |           node-version: "10.24"
 83 |           npm-i: mocha@8.4.0 nyc@15.1.0
 84 | 
 85 |         - name: Node.js 11.x
 86 |           node-version: "11.15"
 87 |           npm-i: mocha@8.4.0 nyc@15.1.0
 88 | 
 89 |         - name: Node.js 12.x
 90 |           node-version: "12.22"
 91 |           npm-i: mocha@9.2.2 nyc@15.1.0
 92 | 
 93 |         - name: Node.js 13.x
 94 |           node-version: "13.14"
 95 |           npm-i: mocha@9.2.2 nyc@15.1.0
 96 | 
 97 |         - name: Node.js 14.x
 98 |           node-version: "14.21"
 99 |           npm-i: nyc@15.1.0
100 | 
101 |         - name: Node.js 15.x
102 |           node-version: "15.14"
103 |           npm-i: nyc@15.1.0
104 | 
105 |         - name: Node.js 16.x
106 |           node-version: "16.20"
107 |           npm-i: nyc@15.1.0
108 | 
109 |         - name: Node.js 17.x
110 |           node-version: "17.9"
111 |           npm-i: nyc@15.1.0
112 | 
113 |         - name: Node.js 18.x
114 |           node-version: "18.19"
115 | 
116 |         - name: Node.js 20.x
117 |           node-version: "20.11"
118 | 
119 |         - name: Node.js 21.x
120 |           node-version: "21.6"
121 | 
122 |     steps:
123 |     - uses: actions/checkout@v4
124 | 
125 |     - name: Install Node.js ${{ matrix.node-version }}
126 |       shell: bash -eo pipefail -l {0}
127 |       run: |
128 |         nvm install --default ${{ matrix.node-version }}
129 |         dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH"
130 | 
131 |     - name: Configure npm
132 |       run: |
133 |         if [[ "$(npm config get package-lock)" == "true" ]]; then
134 |           npm config set package-lock false
135 |         else
136 |           npm config set shrinkwrap false
137 |         fi
138 | 
139 |     - name: Remove npm module(s) ${{ matrix.npm-rm }}
140 |       run: npm rm --silent --save-dev ${{ matrix.npm-rm }}
141 |       if: matrix.npm-rm != ''
142 | 
143 |     - name: Install npm module(s) ${{ matrix.npm-i }}
144 |       run: npm install --save-dev ${{ matrix.npm-i }}
145 |       if: matrix.npm-i != ''
146 | 
147 |     - name: Setup Node.js version-specific dependencies
148 |       shell: bash
149 |       run: |
150 |         # eslint for linting
151 |         # - remove on Node.js < 12
152 |         if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 12 ]]; then
153 |           node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \
154 |             grep -E '^eslint(-|$)' | \
155 |             sort -r | \
156 |             xargs -n1 npm rm --silent --save-dev
157 |         fi
158 | 
159 |     - name: Install Node.js dependencies
160 |       run: npm install
161 | 
162 |     - name: List environment
163 |       id: list_env
164 |       shell: bash
165 |       run: |
166 |         echo "node@$(node -v)"
167 |         echo "npm@$(npm -v)"
168 |         npm -s ls ||:
169 |         (npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print $2 "=" $3 }' >> "$GITHUB_OUTPUT"
170 | 
171 |     - name: Run tests
172 |       shell: bash
173 |       run: |
174 |         if npm -ps ls nyc | grep -q nyc; then
175 |           npm run test-ci
176 |         else
177 |           npm test
178 |         fi
179 | 
180 |     - name: Lint code
181 |       if: steps.list_env.outputs.eslint != ''
182 |       run: npm run lint
183 | 
184 |     - name: Collect code coverage
185 |       uses: coverallsapp/github-action@master
186 |       if: steps.list_env.outputs.nyc != ''
187 |       with:
188 |         github-token: ${{ secrets.GITHUB_TOKEN }}
189 |         flag-name: run-${{ matrix.test_number }}
190 |         parallel: true
191 | 
192 |   coverage:
193 |     needs: test
194 |     runs-on: ubuntu-latest
195 |     steps:
196 |     - name: Uploade code coverage
197 |       uses: coverallsapp/github-action@master
198 |       with:
199 |         github-token: ${{ secrets.github_token }}
200 |         parallel-finished: true
201 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .nyc_output/
2 | coverage/
3 | node_modules/
4 | npm-debug.log
5 | package-lock.json
6 | 


--------------------------------------------------------------------------------
/HISTORY.md:
--------------------------------------------------------------------------------
   1 | 3.7.0 / 2019-05-17
   2 | ==================
   3 | 
   4 |   * deps: finalhandler@1.1.2
   5 |     - Set stricter `Content-Security-Policy` header
   6 |     - Fix 404 output for bad / missing pathnames
   7 |     - deps: encodeurl@~1.0.2
   8 |     - deps: parseurl@~1.3.3
   9 |     - deps: statuses@~1.4.0
  10 |   * deps: parseurl@~1.3.3
  11 |   * perf: remove substr call from FQDN mapping
  12 | 
  13 | 3.6.6 / 2018-02-14
  14 | ==================
  15 | 
  16 |   * deps: finalhandler@1.1.0
  17 |     - Use `res.headersSent` when available
  18 |   * perf: remove array read-past-end
  19 | 
  20 | 3.6.5 / 2017-09-22
  21 | ==================
  22 | 
  23 |   * deps: debug@2.6.9
  24 |   * deps: finalhandler@1.0.6
  25 |     - deps: debug@2.6.9
  26 | 
  27 | 3.6.4 / 2017-09-20
  28 | ==================
  29 | 
  30 |   * deps: finalhandler@1.0.5
  31 |     - deps: parseurl@~1.3.2
  32 |   * deps: parseurl@~1.3.2
  33 |     - perf: reduce overhead for full URLs
  34 |     - perf: unroll the "fast-path" `RegExp`
  35 |   * deps: utils-merge@1.0.1
  36 | 
  37 | 3.6.3 / 2017-08-03
  38 | ==================
  39 | 
  40 |   * deps: debug@2.6.8
  41 |   * deps: finalhandler@1.0.4
  42 |     - deps: debug@2.6.8
  43 | 
  44 | 3.6.2 / 2017-05-16
  45 | ==================
  46 | 
  47 |   * deps: finalhandler@1.0.3
  48 |     - deps: debug@2.6.7
  49 |   * deps: debug@2.6.7
  50 |     - deps: ms@2.0.0
  51 | 
  52 | 3.6.1 / 2017-04-19
  53 | ==================
  54 | 
  55 |   * deps: debug@2.6.3
  56 |     - Fix `DEBUG_MAX_ARRAY_LENGTH`
  57 |   * deps: finalhandler@1.0.1
  58 |     - Fix missing `</html>` in HTML document
  59 |     - deps: debug@2.6.3
  60 | 
  61 | 3.6.0 / 2017-02-17
  62 | ==================
  63 | 
  64 |   * deps: debug@2.6.1
  65 |     - Allow colors in workers
  66 |     - Deprecated `DEBUG_FD` environment variable set to `3` or higher
  67 |     - Fix error when running under React Native
  68 |     - Use same color for same namespace
  69 |     - deps: ms@0.7.2
  70 |   * deps: finalhandler@1.0.0
  71 |     - Fix exception when `err` cannot be converted to a string
  72 |     - Fully URL-encode the pathname in the 404
  73 |     - Only include the pathname in the 404 message
  74 |     - Send complete HTML document
  75 |     - Set `Content-Security-Policy: default-src 'self'` header
  76 |     - deps: debug@2.6.1
  77 | 
  78 | 3.5.1 / 2017-02-12
  79 | ==================
  80 | 
  81 |   * deps: finalhandler@0.5.1
  82 |     - Fix exception when `err.headers` is not an object
  83 |     - deps: statuses@~1.3.1
  84 |     - perf: hoist regular expressions
  85 |     - perf: remove duplicate validation path
  86 | 
  87 | 3.5.0 / 2016-09-09
  88 | ==================
  89 | 
  90 |   * deps: finalhandler@0.5.0
  91 |     - Change invalid or non-numeric status code to 500
  92 |     - Overwrite status message to match set status code
  93 |     - Prefer `err.statusCode` if `err.status` is invalid
  94 |     - Set response headers from `err.headers` object
  95 |     - Use `statuses` instead of `http` module for status messages
  96 | 
  97 | 3.4.1 / 2016-01-23
  98 | ==================
  99 | 
 100 |   * deps: finalhandler@0.4.1
 101 |     - deps: escape-html@~1.0.3
 102 |   * deps: parseurl@~1.3.1
 103 |     - perf: enable strict mode
 104 | 
 105 | 3.4.0 / 2015-06-18
 106 | ==================
 107 | 
 108 |   * deps: debug@~2.2.0
 109 |     - deps: ms@0.7.1
 110 |   * deps: finalhandler@0.4.0
 111 |     - Fix a false-positive when unpiping in Node.js 0.8
 112 |     - Support `statusCode` property on `Error` objects
 113 |     - Use `unpipe` module for unpiping requests
 114 |     - deps: debug@~2.2.0
 115 |     - deps: escape-html@1.0.2
 116 |     - deps: on-finished@~2.3.0
 117 |     - perf: enable strict mode
 118 |     - perf: remove argument reassignment
 119 |   * perf: enable strict mode
 120 |   * perf: remove argument reassignments
 121 | 
 122 | 3.3.5 / 2015-03-16
 123 | ==================
 124 | 
 125 |   * deps: debug@~2.1.3
 126 |     - Fix high intensity foreground color for bold
 127 |     - deps: ms@0.7.0
 128 |   * deps: finalhandler@0.3.4
 129 |     - deps: debug@~2.1.3
 130 | 
 131 | 3.3.4 / 2015-01-07
 132 | ==================
 133 | 
 134 |   * deps: debug@~2.1.1
 135 |   * deps: finalhandler@0.3.3
 136 |     - deps: debug@~2.1.1
 137 |     - deps: on-finished@~2.2.0
 138 | 
 139 | 3.3.3 / 2014-11-09
 140 | ==================
 141 | 
 142 |   * Correctly invoke async callback asynchronously
 143 | 
 144 | 3.3.2 / 2014-10-28
 145 | ==================
 146 | 
 147 |   * Fix handling of URLs containing `://` in the path
 148 | 
 149 | 3.3.1 / 2014-10-22
 150 | ==================
 151 | 
 152 |   * deps: finalhandler@0.3.2
 153 |     - deps: on-finished@~2.1.1
 154 | 
 155 | 3.3.0 / 2014-10-17
 156 | ==================
 157 | 
 158 |   * deps: debug@~2.1.0
 159 |     - Implement `DEBUG_FD` env variable support
 160 |   * deps: finalhandler@0.3.1
 161 |     - Terminate in progress response only on error
 162 |     - Use `on-finished` to determine request status
 163 |     - deps: debug@~2.1.0
 164 | 
 165 | 3.2.0 / 2014-09-08
 166 | ==================
 167 | 
 168 |   * deps: debug@~2.0.0
 169 |   * deps: finalhandler@0.2.0
 170 |     - Set `X-Content-Type-Options: nosniff` header
 171 |     - deps: debug@~2.0.0
 172 | 
 173 | 3.1.1 / 2014-08-10
 174 | ==================
 175 | 
 176 |   * deps: parseurl@~1.3.0
 177 | 
 178 | 3.1.0 / 2014-07-22
 179 | ==================
 180 | 
 181 |   * deps: debug@1.0.4
 182 |   * deps: finalhandler@0.1.0
 183 |     - Respond after request fully read
 184 |     - deps: debug@1.0.4
 185 |   * deps: parseurl@~1.2.0
 186 |     - Cache URLs based on original value
 187 |     - Remove no-longer-needed URL mis-parse work-around
 188 |     - Simplify the "fast-path" `RegExp`
 189 |   * perf: reduce executed logic in routing
 190 |   * perf: refactor location of `try` block
 191 | 
 192 | 3.0.2 / 2014-07-10
 193 | ==================
 194 | 
 195 |   * deps: debug@1.0.3
 196 |     - Add support for multiple wildcards in namespaces
 197 |   * deps: parseurl@~1.1.3
 198 |     - faster parsing of href-only URLs
 199 | 
 200 | 3.0.1 / 2014-06-19
 201 | ==================
 202 | 
 203 |   * use `finalhandler` for final response handling
 204 |   * deps: debug@1.0.2
 205 | 
 206 | 3.0.0 / 2014-05-29
 207 | ==================
 208 | 
 209 |   * No changes
 210 | 
 211 | 3.0.0-rc.2 / 2014-05-04
 212 | =======================
 213 | 
 214 |   * Call error stack even when response has been sent
 215 |   * Prevent default 404 handler after response sent
 216 |   * dep: debug@0.8.1
 217 |   * encode stack in HTML for default error handler
 218 |   * remove `proto` export
 219 | 
 220 | 3.0.0-rc.1 / 2014-03-06
 221 | =======================
 222 | 
 223 |   * move middleware to separate repos
 224 |   * remove docs
 225 |   * remove node patches
 226 |   * remove connect(middleware...)
 227 |   * remove the old `connect.createServer()` method
 228 |   * remove various private `connect.utils` functions
 229 |   * drop node.js 0.8 support
 230 | 
 231 | 2.30.2 / 2015-07-31
 232 | ===================
 233 | 
 234 |   * deps: body-parser@~1.13.3
 235 |     - deps: type-is@~1.6.6
 236 |   * deps: compression@~1.5.2
 237 |     - deps: accepts@~1.2.12
 238 |     - deps: compressible@~2.0.5
 239 |     - deps: vary@~1.0.1
 240 |   * deps: errorhandler@~1.4.2
 241 |     - deps: accepts@~1.2.12
 242 |   * deps: method-override@~2.3.5
 243 |     - deps: vary@~1.0.1
 244 |     - perf: enable strict mode
 245 |   * deps: serve-index@~1.7.2
 246 |     - deps: accepts@~1.2.12
 247 |     - deps: mime-types@~2.1.4
 248 |   * deps: type-is@~1.6.6
 249 |     - deps: mime-types@~2.1.4
 250 |   * deps: vhost@~3.0.1
 251 |     - perf: enable strict mode
 252 | 
 253 | 2.30.1 / 2015-07-05
 254 | ===================
 255 | 
 256 |   * deps: body-parser@~1.13.2
 257 |     - deps: iconv-lite@0.4.11
 258 |     - deps: qs@4.0.0
 259 |     - deps: raw-body@~2.1.2
 260 |     - deps: type-is@~1.6.4
 261 |   * deps: compression@~1.5.1
 262 |     - deps: accepts@~1.2.10
 263 |     - deps: compressible@~2.0.4
 264 |   * deps: errorhandler@~1.4.1
 265 |     - deps: accepts@~1.2.10
 266 |   * deps: qs@4.0.0
 267 |     - Fix dropping parameters like `hasOwnProperty`
 268 |     - Fix various parsing edge cases
 269 |   * deps: morgan@~1.6.1
 270 |     - deps: basic-auth@~1.0.3
 271 |   * deps: pause@0.1.0
 272 |     - Re-emit events with all original arguments
 273 |     - Refactor internals
 274 |     - perf: enable strict mode
 275 |   * deps: serve-index@~1.7.1
 276 |     - deps: accepts@~1.2.10
 277 |     - deps: mime-types@~2.1.2
 278 |   * deps: type-is@~1.6.4
 279 |     - deps: mime-types@~2.1.2
 280 |     - perf: enable strict mode
 281 |     - perf: remove argument reassignment
 282 | 
 283 | 2.30.0 / 2015-06-18
 284 | ===================
 285 | 
 286 |   * deps: body-parser@~1.13.1
 287 |     - Add `statusCode` property on `Error`s, in addition to `status`
 288 |     - Change `type` default to `application/json` for JSON parser
 289 |     - Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser
 290 |     - Provide static `require` analysis
 291 |     - Use the `http-errors` module to generate errors
 292 |     - deps: bytes@2.1.0
 293 |     - deps: iconv-lite@0.4.10
 294 |     - deps: on-finished@~2.3.0
 295 |     - deps: raw-body@~2.1.1
 296 |     - deps: type-is@~1.6.3
 297 |     - perf: enable strict mode
 298 |     - perf: remove argument reassignment
 299 |     - perf: remove delete call
 300 |   * deps: bytes@2.1.0
 301 |     - Slight optimizations
 302 |     - Units no longer case sensitive when parsing
 303 |   * deps: compression@~1.5.0
 304 |     - Fix return value from `.end` and `.write` after end
 305 |     - Improve detection of zero-length body without `Content-Length`
 306 |     - deps: accepts@~1.2.9
 307 |     - deps: bytes@2.1.0
 308 |     - deps: compressible@~2.0.3
 309 |     - perf: enable strict mode
 310 |     - perf: remove flush reassignment
 311 |     - perf: simplify threshold detection
 312 |   * deps: cookie@0.1.3
 313 |     - Slight optimizations
 314 |   * deps: cookie-parser@~1.3.5
 315 |     - deps: cookie@0.1.3
 316 |   * deps: csurf@~1.8.3
 317 |     - Add `sessionKey` option
 318 |     - deps: cookie@0.1.3
 319 |     - deps: csrf@~3.0.0
 320 |   * deps: errorhandler@~1.4.0
 321 |     - Add charset to the `Content-Type` header
 322 |     - Support `statusCode` property on `Error` objects
 323 |     - deps: accepts@~1.2.9
 324 |     - deps: escape-html@1.0.2
 325 |   * deps: express-session@~1.11.3
 326 |     - Support an array in `secret` option for key rotation
 327 |     - deps: cookie@0.1.3
 328 |     - deps: crc@3.3.0
 329 |     - deps: debug@~2.2.0
 330 |     - deps: depd@~1.0.1
 331 |     - deps: uid-safe@~2.0.0
 332 |   * deps: finalhandler@0.4.0
 333 |     - Fix a false-positive when unpiping in Node.js 0.8
 334 |     - Support `statusCode` property on `Error` objects
 335 |     - Use `unpipe` module for unpiping requests
 336 |     - deps: escape-html@1.0.2
 337 |     - deps: on-finished@~2.3.0
 338 |     - perf: enable strict mode
 339 |     - perf: remove argument reassignment
 340 |   * deps: fresh@0.3.0
 341 |     - Add weak `ETag` matching support
 342 |   * deps: morgan@~1.6.0
 343 |     - Add `morgan.compile(format)` export
 344 |     - Do not color 1xx status codes in `dev` format
 345 |     - Fix `response-time` token to not include response latency
 346 |     - Fix `status` token incorrectly displaying before response in `dev` format
 347 |     - Fix token return values to be `undefined` or a string
 348 |     - Improve representation of multiple headers in `req` and `res` tokens
 349 |     - Use `res.getHeader` in `res` token
 350 |     - deps: basic-auth@~1.0.2
 351 |     - deps: on-finished@~2.3.0
 352 |     - pref: enable strict mode
 353 |     - pref: reduce function closure scopes
 354 |     - pref: remove dynamic compile on every request for `dev` format
 355 |     - pref: remove an argument reassignment
 356 |     - pref: skip function call without `skip` option
 357 |   * deps: serve-favicon@~2.3.0
 358 |     - Send non-chunked response for `OPTIONS`
 359 |     - deps: etag@~1.7.0
 360 |     - deps: fresh@0.3.0
 361 |     - perf: enable strict mode
 362 |     - perf: remove argument reassignment
 363 |     - perf: remove bitwise operations
 364 |   * deps: serve-index@~1.7.0
 365 |     - Accept `function` value for `template` option
 366 |     - Send non-chunked response for `OPTIONS`
 367 |     - Stat parent directory when necessary
 368 |     - Use `Date.prototype.toLocaleDateString` to format date
 369 |     - deps: accepts@~1.2.9
 370 |     - deps: escape-html@1.0.2
 371 |     - deps: mime-types@~2.1.1
 372 |     - perf: enable strict mode
 373 |     - perf: remove argument reassignment
 374 |   * deps: serve-static@~1.10.0
 375 |     - Add `fallthrough` option
 376 |     - Fix reading options from options prototype
 377 |     - Improve the default redirect response headers
 378 |     - Malformed URLs now `next()` instead of 400
 379 |     - deps: escape-html@1.0.2
 380 |     - deps: send@0.13.0
 381 |     - perf: enable strict mode
 382 |     - perf: remove argument reassignment
 383 |   * deps: type-is@~1.6.3
 384 |     - deps: mime-types@~2.1.1
 385 |     - perf: reduce try block size
 386 |     - perf: remove bitwise operations
 387 | 
 388 | 2.29.2 / 2015-05-14
 389 | ===================
 390 | 
 391 |   * deps: body-parser@~1.12.4
 392 |     - Slight efficiency improvement when not debugging
 393 |     - deps: debug@~2.2.0
 394 |     - deps: depd@~1.0.1
 395 |     - deps: iconv-lite@0.4.8
 396 |     - deps: on-finished@~2.2.1
 397 |     - deps: qs@2.4.2
 398 |     - deps: raw-body@~2.0.1
 399 |     - deps: type-is@~1.6.2
 400 |   * deps: compression@~1.4.4
 401 |     - deps: accepts@~1.2.7
 402 |     - deps: debug@~2.2.0
 403 |   * deps: connect-timeout@~1.6.2
 404 |     - deps: debug@~2.2.0
 405 |     - deps: ms@0.7.1
 406 |   * deps: debug@~2.2.0
 407 |     - deps: ms@0.7.1
 408 |   * deps: depd@~1.0.1
 409 |   * deps: errorhandler@~1.3.6
 410 |     - deps: accepts@~1.2.7
 411 |   * deps: finalhandler@0.3.6
 412 |     - deps: debug@~2.2.0
 413 |     - deps: on-finished@~2.2.1
 414 |   * deps: method-override@~2.3.3
 415 |     - deps: debug@~2.2.0
 416 |   * deps: morgan@~1.5.3
 417 |     - deps: basic-auth@~1.0.1
 418 |     - deps: debug@~2.2.0
 419 |     - deps: depd@~1.0.1
 420 |     - deps: on-finished@~2.2.1
 421 |   * deps: qs@2.4.2
 422 |     - Fix allowing parameters like `constructor`
 423 |   * deps: response-time@~2.3.1
 424 |     - deps: depd@~1.0.1
 425 |   * deps: serve-favicon@~2.2.1
 426 |     - deps: etag@~1.6.0
 427 |     - deps: ms@0.7.1
 428 |   * deps: serve-index@~1.6.4
 429 |     - deps: accepts@~1.2.7
 430 |     - deps: debug@~2.2.0
 431 |     - deps: mime-types@~2.0.11
 432 |   * deps: serve-static@~1.9.3
 433 |     - deps: send@0.12.3
 434 |   * deps: type-is@~1.6.2
 435 |     - deps: mime-types@~2.0.11
 436 | 
 437 | 2.29.1 / 2015-03-16
 438 | ===================
 439 | 
 440 |   * deps: body-parser@~1.12.2
 441 |     - deps: debug@~2.1.3
 442 |     - deps: qs@2.4.1
 443 |     - deps: type-is@~1.6.1
 444 |   * deps: compression@~1.4.3
 445 |     - Fix error when code calls `res.end(str, encoding)`
 446 |     - deps: accepts@~1.2.5
 447 |     - deps: debug@~2.1.3
 448 |   * deps: connect-timeout@~1.6.1
 449 |     - deps: debug@~2.1.3
 450 |   * deps: debug@~2.1.3
 451 |     - Fix high intensity foreground color for bold
 452 |     - deps: ms@0.7.0
 453 |   * deps: errorhandler@~1.3.5
 454 |     - deps: accepts@~1.2.5
 455 |   * deps: express-session@~1.10.4
 456 |     - deps: debug@~2.1.3
 457 |   * deps: finalhandler@0.3.4
 458 |     - deps: debug@~2.1.3
 459 |   * deps: method-override@~2.3.2
 460 |     - deps: debug@~2.1.3
 461 |   * deps: morgan@~1.5.2
 462 |     - deps: debug@~2.1.3
 463 |   * deps: qs@2.4.1
 464 |     - Fix error when parameter `hasOwnProperty` is present
 465 |   * deps: serve-index@~1.6.3
 466 |     - Properly escape file names in HTML
 467 |     - deps: accepts@~1.2.5
 468 |     - deps: debug@~2.1.3
 469 |     - deps: escape-html@1.0.1
 470 |     - deps: mime-types@~2.0.10
 471 |   * deps: serve-static@~1.9.2
 472 |     - deps: send@0.12.2
 473 |   * deps: type-is@~1.6.1
 474 |     - deps: mime-types@~2.0.10
 475 | 
 476 | 2.29.0 / 2015-02-17
 477 | ===================
 478 | 
 479 |   * Use `content-type` to parse `Content-Type` headers
 480 |   * deps: body-parser@~1.12.0
 481 |     - add `debug` messages
 482 |     - accept a function for the `type` option
 483 |     - make internal `extended: true` depth limit infinity
 484 |     - use `content-type` to parse `Content-Type` headers
 485 |     - deps: iconv-lite@0.4.7
 486 |     - deps: raw-body@1.3.3
 487 |     - deps: type-is@~1.6.0
 488 |   * deps: compression@~1.4.1
 489 |     - Prefer `gzip` over `deflate` on the server
 490 |     - deps: accepts@~1.2.4
 491 |   * deps: connect-timeout@~1.6.0
 492 |     - deps: http-errors@~1.3.1
 493 |   * deps: cookie-parser@~1.3.4
 494 |     - deps: cookie-signature@1.0.6
 495 |   * deps: cookie-signature@1.0.6
 496 |   * deps: csurf@~1.7.0
 497 |     - Accept `CSRF-Token` and `XSRF-Token` request headers
 498 |     - Default `cookie.path` to `'/'`, if using cookies
 499 |     - deps: cookie-signature@1.0.6
 500 |     - deps: csrf@~2.0.6
 501 |     - deps: http-errors@~1.3.1
 502 |   * deps: errorhandler@~1.3.4
 503 |     - deps: accepts@~1.2.4
 504 |   * deps: express-session@~1.10.3
 505 |     - deps: cookie-signature@1.0.6
 506 |     - deps: uid-safe@1.1.0
 507 |   * deps: http-errors@~1.3.1
 508 |     - Construct errors using defined constructors from `createError`
 509 |     - Fix error names that are not identifiers
 510 |     - Set a meaningful `name` property on constructed errors
 511 |   * deps: response-time@~2.3.0
 512 |     - Add function argument to support recording of response time
 513 |   * deps: serve-index@~1.6.2
 514 |     - deps: accepts@~1.2.4
 515 |     - deps: http-errors@~1.3.1
 516 |     - deps: mime-types@~2.0.9
 517 |   * deps: serve-static@~1.9.1
 518 |     - deps: send@0.12.1
 519 |   * deps: type-is@~1.6.0
 520 |     - fix argument reassignment
 521 |     - fix false-positives in `hasBody` `Transfer-Encoding` check
 522 |     - support wildcard for both type and subtype (`*/*`)
 523 |     - deps: mime-types@~2.0.9
 524 | 
 525 | 2.28.3 / 2015-01-31
 526 | ===================
 527 | 
 528 |   * deps: compression@~1.3.1
 529 |     - deps: accepts@~1.2.3
 530 |     - deps: compressible@~2.0.2
 531 |   * deps: csurf@~1.6.6
 532 |     - deps: csrf@~2.0.5
 533 |   * deps: errorhandler@~1.3.3
 534 |     - deps: accepts@~1.2.3
 535 |   * deps: express-session@~1.10.2
 536 |     - deps: uid-safe@1.0.3
 537 |   * deps: serve-index@~1.6.1
 538 |     - deps: accepts@~1.2.3
 539 |     - deps: mime-types@~2.0.8
 540 |   * deps: type-is@~1.5.6
 541 |     - deps: mime-types@~2.0.8
 542 | 
 543 | 2.28.2 / 2015-01-20
 544 | ===================
 545 | 
 546 |   * deps: body-parser@~1.10.2
 547 |     - deps: iconv-lite@0.4.6
 548 |     - deps: raw-body@1.3.2
 549 |   * deps: serve-static@~1.8.1
 550 |     - Fix redirect loop in Node.js 0.11.14
 551 |     - Fix root path disclosure
 552 |     - deps: send@0.11.1
 553 | 
 554 | 2.28.1 / 2015-01-08
 555 | ===================
 556 | 
 557 |   * deps: csurf@~1.6.5
 558 |     - deps: csrf@~2.0.4
 559 |   * deps: express-session@~1.10.1
 560 |     - deps: uid-safe@~1.0.2
 561 | 
 562 | 2.28.0 / 2015-01-05
 563 | ===================
 564 | 
 565 |   * deps: body-parser@~1.10.1
 566 |     - Make internal `extended: true` array limit dynamic
 567 |     - deps: on-finished@~2.2.0
 568 |     - deps: type-is@~1.5.5
 569 |   * deps: compression@~1.3.0
 570 |     - Export the default `filter` function for wrapping
 571 |     - deps: accepts@~1.2.2
 572 |     - deps: debug@~2.1.1
 573 |   * deps: connect-timeout@~1.5.0
 574 |     - deps: debug@~2.1.1
 575 |     - deps: http-errors@~1.2.8
 576 |     - deps: ms@0.7.0
 577 |   * deps: csurf@~1.6.4
 578 |     - deps: csrf@~2.0.3
 579 |     - deps: http-errors@~1.2.8
 580 |   * deps: debug@~2.1.1
 581 |   * deps: errorhandler@~1.3.2
 582 |     - Add `log` option
 583 |     - Fix heading content to not include stack
 584 |     - deps: accepts@~1.2.2
 585 |   * deps: express-session@~1.10.0
 586 |     - Add `store.touch` interface for session stores
 587 |     - Fix `MemoryStore` expiration with `resave: false`
 588 |     - deps: debug@~2.1.1
 589 |   * deps: finalhandler@0.3.3
 590 |     - deps: debug@~2.1.1
 591 |     - deps: on-finished@~2.2.0
 592 |   * deps: method-override@~2.3.1
 593 |     - deps: debug@~2.1.1
 594 |     - deps: methods@~1.1.1
 595 |   * deps: morgan@~1.5.1
 596 |     - Add multiple date formats `clf`, `iso`, and `web`
 597 |     - Deprecate `buffer` option
 598 |     - Fix date format in `common` and `combined` formats
 599 |     - Fix token arguments to accept values with `"`
 600 |     - deps: debug@~2.1.1
 601 |     - deps: on-finished@~2.2.0
 602 |   * deps: serve-favicon@~2.2.0
 603 |     - Support query string in the URL
 604 |     - deps: etag@~1.5.1
 605 |     - deps: ms@0.7.0
 606 |   * deps: serve-index@~1.6.0
 607 |     - Add link to root directory
 608 |     - deps: accepts@~1.2.2
 609 |     - deps: batch@0.5.2
 610 |     - deps: debug@~2.1.1
 611 |     - deps: mime-types@~2.0.7
 612 |   * deps: serve-static@~1.8.0
 613 |     - Fix potential open redirect when mounted at root
 614 |     - deps: send@0.11.0
 615 |   * deps: type-is@~1.5.5
 616 |     - deps: mime-types@~2.0.7
 617 | 
 618 | 2.27.6 / 2014-12-10
 619 | ===================
 620 | 
 621 |   * deps: serve-index@~1.5.3
 622 |     - deps: accepts@~1.1.4
 623 |     - deps: http-errors@~1.2.8
 624 |     - deps: mime-types@~2.0.4
 625 | 
 626 | 2.27.5 / 2014-12-10
 627 | ===================
 628 | 
 629 |   * deps: compression@~1.2.2
 630 |     - Fix `.end` to only proxy to `.end`
 631 |     - deps: accepts@~1.1.4
 632 |   * deps: express-session@~1.9.3
 633 |     - Fix error when `req.sessionID` contains a non-string value
 634 |   * deps: http-errors@~1.2.8
 635 |     - Fix stack trace from exported function
 636 |     - Remove `arguments.callee` usage
 637 |   * deps: serve-index@~1.5.2
 638 |     - Fix icon name background alignment on mobile view
 639 |   * deps: type-is@~1.5.4
 640 |     - deps: mime-types@~2.0.4
 641 | 
 642 | 2.27.4 / 2014-11-23
 643 | ===================
 644 | 
 645 |   * deps: body-parser@~1.9.3
 646 |     - deps: iconv-lite@0.4.5
 647 |     - deps: qs@2.3.3
 648 |     - deps: raw-body@1.3.1
 649 |     - deps: type-is@~1.5.3
 650 |   * deps: compression@~1.2.1
 651 |     - deps: accepts@~1.1.3
 652 |   * deps: errorhandler@~1.2.3
 653 |     - deps: accepts@~1.1.3
 654 |   * deps: express-session@~1.9.2
 655 |     - deps: crc@3.2.1
 656 |   * deps: qs@2.3.3
 657 |     - Fix `arrayLimit` behavior
 658 |   * deps: serve-favicon@~2.1.7
 659 |     - Avoid errors from enumerables on `Object.prototype`
 660 |   * deps: serve-index@~1.5.1
 661 |     - deps: accepts@~1.1.3
 662 |     - deps: mime-types@~2.0.3
 663 |   * deps: type-is@~1.5.3
 664 |     - deps: mime-types@~2.0.3
 665 | 
 666 | 2.27.3 / 2014-11-09
 667 | ===================
 668 | 
 669 |   * Correctly invoke async callback asynchronously
 670 |   * deps: csurf@~1.6.3
 671 |     - bump csrf
 672 |     - bump http-errors
 673 | 
 674 | 2.27.2 / 2014-10-28
 675 | ===================
 676 | 
 677 |   * Fix handling of URLs containing `://` in the path
 678 |   * deps: body-parser@~1.9.2
 679 |     - deps: qs@2.3.2
 680 |   * deps: qs@2.3.2
 681 |     - Fix parsing of mixed objects and values
 682 | 
 683 | 2.27.1 / 2014-10-22
 684 | ===================
 685 | 
 686 |   * deps: body-parser@~1.9.1
 687 |     - deps: on-finished@~2.1.1
 688 |     - deps: qs@2.3.0
 689 |     - deps: type-is@~1.5.2
 690 |   * deps: express-session@~1.9.1
 691 |     - Remove unnecessary empty write call
 692 |   * deps: finalhandler@0.3.2
 693 |     - deps: on-finished@~2.1.1
 694 |   * deps: morgan@~1.4.1
 695 |     - deps: on-finished@~2.1.1
 696 |   * deps: qs@2.3.0
 697 |     - Fix parsing of mixed implicit and explicit arrays
 698 |   * deps: serve-static@~1.7.1
 699 |     - deps: send@0.10.1
 700 | 
 701 | 2.27.0 / 2014-10-16
 702 | ===================
 703 | 
 704 |   * Use `http-errors` module for creating errors
 705 |   * Use `utils-merge` module for merging objects
 706 |   * deps: body-parser@~1.9.0
 707 |     - include the charset in "unsupported charset" error message
 708 |     - include the encoding in "unsupported content encoding" error message
 709 |     - deps: depd@~1.0.0
 710 |   * deps: compression@~1.2.0
 711 |     - deps: debug@~2.1.0
 712 |   * deps: connect-timeout@~1.4.0
 713 |     - Create errors with `http-errors`
 714 |     - deps: debug@~2.1.0
 715 |   * deps: debug@~2.1.0
 716 |     - Implement `DEBUG_FD` env variable support
 717 |   * deps: depd@~1.0.0
 718 |   * deps: express-session@~1.9.0
 719 |     - deps: debug@~2.1.0
 720 |     - deps: depd@~1.0.0
 721 |   * deps: finalhandler@0.3.1
 722 |     - Terminate in progress response only on error
 723 |     - Use `on-finished` to determine request status
 724 |     - deps: debug@~2.1.0
 725 |   * deps: method-override@~2.3.0
 726 |     - deps: debug@~2.1.0
 727 |   * deps: morgan@~1.4.0
 728 |     - Add `debug` messages
 729 |     - deps: depd@~1.0.0
 730 |   * deps: response-time@~2.2.0
 731 |     - Add `header` option for custom header name
 732 |     - Add `suffix` option
 733 |     - Change `digits` argument to an `options` argument
 734 |     - deps: depd@~1.0.0
 735 |   * deps: serve-favicon@~2.1.6
 736 |     - deps: etag@~1.5.0
 737 |   * deps: serve-index@~1.5.0
 738 |     - Add `dir` argument to `filter` function
 739 |     - Add icon for mkv files
 740 |     - Create errors with `http-errors`
 741 |     - Fix incorrect 403 on Windows and Node.js 0.11
 742 |     - Lookup icon by mime type for greater icon support
 743 |     - Support using tokens multiple times
 744 |     - deps: accepts@~1.1.2
 745 |     - deps: debug@~2.1.0
 746 |     - deps: mime-types@~2.0.2
 747 |   * deps: serve-static@~1.7.0
 748 |     - deps: send@0.10.0
 749 | 
 750 | 2.26.6 / 2014-10-15
 751 | ===================
 752 | 
 753 |   * deps: compression@~1.1.2
 754 |     - deps: accepts@~1.1.2
 755 |     - deps: compressible@~2.0.1
 756 |   * deps: csurf@~1.6.2
 757 |     - bump http-errors
 758 |     - fix cookie name when using `cookie: true`
 759 |   * deps: errorhandler@~1.2.2
 760 |     - deps: accepts@~1.1.2
 761 | 
 762 | 2.26.5 / 2014-10-08
 763 | ===================
 764 | 
 765 |   * Fix accepting non-object arguments to `logger`
 766 |   * deps: serve-static@~1.6.4
 767 |     - Fix redirect loop when index file serving disabled
 768 | 
 769 | 2.26.4 / 2014-10-02
 770 | ===================
 771 | 
 772 |   * deps: morgan@~1.3.2
 773 |     - Fix `req.ip` integration when `immediate: false`
 774 |   * deps: type-is@~1.5.2
 775 |     - deps: mime-types@~2.0.2
 776 | 
 777 | 2.26.3 / 2014-09-24
 778 | ===================
 779 | 
 780 |   * deps: body-parser@~1.8.4
 781 |     - fix content encoding to be case-insensitive
 782 |   * deps: serve-favicon@~2.1.5
 783 |     - deps: etag@~1.4.0
 784 |   * deps: serve-static@~1.6.3
 785 |     - deps: send@0.9.3
 786 | 
 787 | 2.26.2 / 2014-09-19
 788 | ===================
 789 | 
 790 |   * deps: body-parser@~1.8.3
 791 |     - deps: qs@2.2.4
 792 |   * deps: qs@2.2.4
 793 |     - Fix issue with object keys starting with numbers truncated
 794 | 
 795 | 2.26.1 / 2014-09-15
 796 | ===================
 797 | 
 798 |   * deps: body-parser@~1.8.2
 799 |     - deps: depd@0.4.5
 800 |   * deps: depd@0.4.5
 801 |   * deps: express-session@~1.8.2
 802 |     - Use `crc` instead of `buffer-crc32` for speed
 803 |     - deps: depd@0.4.5
 804 |   * deps: morgan@~1.3.1
 805 |     - Remove un-used `bytes` dependency
 806 |     - deps: depd@0.4.5
 807 |   * deps: serve-favicon@~2.1.4
 808 |     - Fix content headers being sent in 304 response
 809 |     - deps: etag@~1.3.1
 810 |   * deps: serve-static@~1.6.2
 811 |     - deps: send@0.9.2
 812 | 
 813 | 2.26.0 / 2014-09-08
 814 | ===================
 815 | 
 816 |   * deps: body-parser@~1.8.1
 817 |     - add `parameterLimit` option to `urlencoded` parser
 818 |     - change `urlencoded` extended array limit to 100
 819 |     - make empty-body-handling consistent between chunked requests
 820 |     - respond with 415 when over `parameterLimit` in `urlencoded`
 821 |     - deps: media-typer@0.3.0
 822 |     - deps: qs@2.2.3
 823 |     - deps: type-is@~1.5.1
 824 |   * deps: compression@~1.1.0
 825 |     - deps: accepts@~1.1.0
 826 |     - deps: compressible@~2.0.0
 827 |     - deps: debug@~2.0.0
 828 |   * deps: connect-timeout@~1.3.0
 829 |     - deps: debug@~2.0.0
 830 |   * deps: cookie-parser@~1.3.3
 831 |     - deps: cookie-signature@1.0.5
 832 |   * deps: cookie-signature@1.0.5
 833 |   * deps: csurf@~1.6.1
 834 |     - add `ignoreMethods` option
 835 |     - bump cookie-signature
 836 |     - csrf-tokens -> csrf
 837 |     - set `code` property on CSRF token errors
 838 |   * deps: debug@~2.0.0
 839 |   * deps: errorhandler@~1.2.0
 840 |     - Display error using `util.inspect` if no other representation
 841 |     - deps: accepts@~1.1.0
 842 |   * deps: express-session@~1.8.1
 843 |     - Do not resave already-saved session at end of request
 844 |     - Prevent session prototype methods from being overwritten
 845 |     - deps: cookie-signature@1.0.5
 846 |     - deps: debug@~2.0.0
 847 |   * deps: finalhandler@0.2.0
 848 |     - Set `X-Content-Type-Options: nosniff` header
 849 |     - deps: debug@~2.0.0
 850 |   * deps: fresh@0.2.4
 851 |   * deps: media-typer@0.3.0
 852 |     - Throw error when parameter format invalid on parse
 853 |   * deps: method-override@~2.2.0
 854 |     - deps: debug@~2.0.0
 855 |   * deps: morgan@~1.3.0
 856 |     - Assert if `format` is not a function or string
 857 |   * deps: qs@2.2.3
 858 |     - Fix issue where first empty value in array is discarded
 859 |   * deps: serve-favicon@~2.1.3
 860 |     - Accept string for `maxAge` (converted by `ms`)
 861 |     - Use `etag` to generate `ETag` header
 862 |     - deps: fresh@0.2.4
 863 |   * deps: serve-index@~1.2.1
 864 |     - Add `debug` messages
 865 |     - Resolve relative paths at middleware setup
 866 |     - deps: accepts@~1.1.0
 867 |   * deps: serve-static@~1.6.1
 868 |     - Add `lastModified` option
 869 |     - deps: send@0.9.1
 870 |   * deps: type-is@~1.5.1
 871 |     - fix `hasbody` to be true for `content-length: 0`
 872 |     - deps: media-typer@0.3.0
 873 |     - deps: mime-types@~2.0.1
 874 |   * deps: vhost@~3.0.0
 875 | 
 876 | 2.25.10 / 2014-09-04
 877 | ====================
 878 | 
 879 |   * deps: serve-static@~1.5.4
 880 |     - deps: send@0.8.5
 881 | 
 882 | 2.25.9 / 2014-08-29
 883 | ===================
 884 | 
 885 |   * deps: body-parser@~1.6.7
 886 |     - deps: qs@2.2.2
 887 |   * deps: qs@2.2.2
 888 | 
 889 | 2.25.8 / 2014-08-27
 890 | ===================
 891 | 
 892 |   * deps: body-parser@~1.6.6
 893 |     - deps: qs@2.2.0
 894 |   * deps: csurf@~1.4.1
 895 |   * deps: qs@2.2.0
 896 |     - Array parsing fix
 897 |     - Performance improvements
 898 | 
 899 | 2.25.7 / 2014-08-18
 900 | ===================
 901 | 
 902 |   * deps: body-parser@~1.6.5
 903 |     - deps: on-finished@2.1.0
 904 |   * deps: express-session@~1.7.6
 905 |     - Fix exception on `res.end(null)` calls
 906 |   * deps: morgan@~1.2.3
 907 |     - deps: on-finished@2.1.0
 908 |   * deps: serve-static@~1.5.3
 909 |     - deps: send@0.8.3
 910 | 
 911 | 2.25.6 / 2014-08-14
 912 | ===================
 913 | 
 914 |   * deps: body-parser@~1.6.4
 915 |     - deps: qs@1.2.2
 916 |   * deps: qs@1.2.2
 917 |   * deps: serve-static@~1.5.2
 918 |     - deps: send@0.8.2
 919 | 
 920 | 2.25.5 / 2014-08-11
 921 | ===================
 922 | 
 923 |   * Fix backwards compatibility in `logger`
 924 | 
 925 | 2.25.4 / 2014-08-10
 926 | ===================
 927 | 
 928 |   * Fix `query` middleware breaking with argument
 929 |     - It never really took one in the first place
 930 |   * deps: body-parser@~1.6.3
 931 |     - deps: qs@1.2.1
 932 |   * deps: compression@~1.0.11
 933 |     - deps: on-headers@~1.0.0
 934 |     - deps: parseurl@~1.3.0
 935 |   * deps: connect-timeout@~1.2.2
 936 |     - deps: on-headers@~1.0.0
 937 |   * deps: express-session@~1.7.5
 938 |     - Fix parsing original URL
 939 |     - deps: on-headers@~1.0.0
 940 |     - deps: parseurl@~1.3.0
 941 |   * deps: method-override@~2.1.3
 942 |   * deps: on-headers@~1.0.0
 943 |   * deps: parseurl@~1.3.0
 944 |   * deps: qs@1.2.1
 945 |   * deps: response-time@~2.0.1
 946 |     - deps: on-headers@~1.0.0
 947 |   * deps: serve-index@~1.1.6
 948 |     - Fix URL parsing
 949 |   * deps: serve-static@~1.5.1
 950 |     - Fix parsing of weird `req.originalUrl` values
 951 |     - deps: parseurl@~1.3.0
 952 |     = deps: utils-merge@1.0.0
 953 | 
 954 | 2.25.3 / 2014-08-07
 955 | ===================
 956 | 
 957 |   * deps: multiparty@3.3.2
 958 |     - Fix potential double-callback
 959 | 
 960 | 2.25.2 / 2014-08-07
 961 | ===================
 962 | 
 963 |   * deps: body-parser@~1.6.2
 964 |     - deps: qs@1.2.0
 965 |   * deps: qs@1.2.0
 966 |     - Fix parsing array of objects
 967 | 
 968 | 2.25.1 / 2014-08-06
 969 | ===================
 970 | 
 971 |   * deps: body-parser@~1.6.1
 972 |     - deps: qs@1.1.0
 973 |   * deps: qs@1.1.0
 974 |     - Accept urlencoded square brackets
 975 |     - Accept empty values in implicit array notation
 976 | 
 977 | 2.25.0 / 2014-08-05
 978 | ===================
 979 | 
 980 |   * deps: body-parser@~1.6.0
 981 |     - deps: qs@1.0.2
 982 |   * deps: compression@~1.0.10
 983 |     - Fix upper-case Content-Type characters prevent compression
 984 |     - deps: compressible@~1.1.1
 985 |   * deps: csurf@~1.4.0
 986 |     - Support changing `req.session` after `csurf` middleware
 987 |     - Calling `res.csrfToken()` after `req.session.destroy()` will now work
 988 |   * deps: express-session@~1.7.4
 989 |     - Fix `res.end` patch to call correct upstream `res.write`
 990 |     - Fix response end delay for non-chunked responses
 991 |   * deps: qs@1.0.2
 992 |     - Complete rewrite
 993 |     - Limits array length to 20
 994 |     - Limits object depth to 5
 995 |     - Limits parameters to 1,000
 996 |   * deps: serve-static@~1.5.0
 997 |     - Add `extensions` option
 998 |     - deps: send@0.8.1
 999 | 
1000 | 2.24.3 / 2014-08-04
1001 | ===================
1002 | 
1003 |   * deps: serve-index@~1.1.5
1004 |     - Fix Content-Length calculation for multi-byte file names
1005 |     - deps: accepts@~1.0.7
1006 |   * deps: serve-static@~1.4.4
1007 |     - Fix incorrect 403 on Windows and Node.js 0.11
1008 |     - deps: send@0.7.4
1009 | 
1010 | 2.24.2 / 2014-07-27
1011 | ===================
1012 | 
1013 |   * deps: body-parser@~1.5.2
1014 |   * deps: depd@0.4.4
1015 |     - Work-around v8 generating empty stack traces
1016 |   * deps: express-session@~1.7.2
1017 |   * deps: morgan@~1.2.2
1018 |   * deps: serve-static@~1.4.2
1019 | 
1020 | 2.24.1 / 2014-07-26
1021 | ===================
1022 | 
1023 |   * deps: body-parser@~1.5.1
1024 |   * deps: depd@0.4.3
1025 |     - Fix exception when global `Error.stackTraceLimit` is too low
1026 |   * deps: express-session@~1.7.1
1027 |   * deps: morgan@~1.2.1
1028 |   * deps: serve-index@~1.1.4
1029 |   * deps: serve-static@~1.4.1
1030 | 
1031 | 2.24.0 / 2014-07-22
1032 | ===================
1033 | 
1034 |   * deps: body-parser@~1.5.0
1035 |     - deps: depd@0.4.2
1036 |     - deps: iconv-lite@0.4.4
1037 |     - deps: raw-body@1.3.0
1038 |     - deps: type-is@~1.3.2
1039 |   * deps: compression@~1.0.9
1040 |     - Add `debug` messages
1041 |     - deps: accepts@~1.0.7
1042 |   * deps: connect-timeout@~1.2.1
1043 |     - Accept string for `time` (converted by `ms`)
1044 |     - deps: debug@1.0.4
1045 |   * deps: debug@1.0.4
1046 |   * deps: depd@0.4.2
1047 |     - Add `TRACE_DEPRECATION` environment variable
1048 |     - Remove non-standard grey color from color output
1049 |     - Support `--no-deprecation` argument
1050 |     - Support `--trace-deprecation` argument
1051 |   * deps: express-session@~1.7.0
1052 |     - Improve session-ending error handling
1053 |     - deps: debug@1.0.4
1054 |     - deps: depd@0.4.2
1055 |   * deps: finalhandler@0.1.0
1056 |     - Respond after request fully read
1057 |     - deps: debug@1.0.4
1058 |   * deps: method-override@~2.1.2
1059 |     - deps: debug@1.0.4
1060 |     - deps: parseurl@~1.2.0
1061 |   * deps: morgan@~1.2.0
1062 |     - Add `:remote-user` token
1063 |     - Add `combined` log format
1064 |     - Add `common` log format
1065 |     - Remove non-standard grey color from `dev` format
1066 |   * deps: multiparty@3.3.1
1067 |   * deps: parseurl@~1.2.0
1068 |     - Cache URLs based on original value
1069 |     - Remove no-longer-needed URL mis-parse work-around
1070 |     - Simplify the "fast-path" `RegExp`
1071 |   * deps: serve-static@~1.4.0
1072 |     - Add `dotfiles` option
1073 |     - deps: parseurl@~1.2.0
1074 |     - deps: send@0.7.0
1075 | 
1076 | 2.23.0 / 2014-07-10
1077 | ===================
1078 | 
1079 |   * deps: debug@1.0.3
1080 |     - Add support for multiple wildcards in namespaces
1081 |   * deps: express-session@~1.6.4
1082 |   * deps: method-override@~2.1.0
1083 |     - add simple debug output
1084 |     - deps: methods@1.1.0
1085 |     - deps: parseurl@~1.1.3
1086 |   * deps: parseurl@~1.1.3
1087 |     - faster parsing of href-only URLs
1088 |   * deps: serve-static@~1.3.1
1089 |     - deps: parseurl@~1.1.3
1090 | 
1091 | 2.22.0 / 2014-07-03
1092 | ===================
1093 | 
1094 |   * deps: csurf@~1.3.0
1095 |     - Fix `cookie.signed` option to actually sign cookie
1096 |   * deps: express-session@~1.6.1
1097 |     - Fix `res.end` patch to return correct value
1098 |     - Fix `res.end` patch to handle multiple `res.end` calls
1099 |     - Reject cookies with missing signatures
1100 |   * deps: multiparty@3.3.0
1101 |     - Always emit close after all parts ended
1102 |     - Fix callback hang in node.js 0.8 on errors
1103 |   * deps: serve-static@~1.3.0
1104 |     - Accept string for `maxAge` (converted by `ms`)
1105 |     - Add `setHeaders` option
1106 |     - Include HTML link in redirect response
1107 |     - deps: send@0.5.0
1108 | 
1109 | 2.21.1 / 2014-06-26
1110 | ===================
1111 | 
1112 |   * deps: cookie-parser@1.3.2
1113 |     - deps: cookie-signature@1.0.4
1114 |   * deps: cookie-signature@1.0.4
1115 |     - fix for timing attacks
1116 |   * deps: express-session@~1.5.2
1117 |     - deps: cookie-signature@1.0.4
1118 |   * deps: type-is@~1.3.2
1119 |     - more mime types
1120 | 
1121 | 2.21.0 / 2014-06-20
1122 | ===================
1123 | 
1124 |   * deprecate `connect(middleware)` -- use `app.use(middleware)` instead
1125 |   * deprecate `connect.createServer()` -- use `connect()` instead
1126 |   * fix `res.setHeader()` patch to work with get -> append -> set pattern
1127 |   * deps: compression@~1.0.8
1128 |   * deps: errorhandler@~1.1.1
1129 |   * deps: express-session@~1.5.0
1130 |     - Deprecate integration with `cookie-parser` middleware
1131 |     - Deprecate looking for secret in `req.secret`
1132 |     - Directly read cookies; `cookie-parser` no longer required
1133 |     - Directly set cookies; `res.cookie` no longer required
1134 |     - Generate session IDs with `uid-safe`, faster and even less collisions
1135 |   * deps: serve-index@~1.1.3
1136 | 
1137 | 2.20.2 / 2014-06-19
1138 | ===================
1139 | 
1140 |   * deps: body-parser@1.4.3
1141 |     - deps: type-is@1.3.1
1142 | 
1143 | 2.20.1 / 2014-06-19
1144 | ===================
1145 | 
1146 |   * deps: type-is@1.3.1
1147 |     - fix global variable leak
1148 | 
1149 | 2.20.0 / 2014-06-19
1150 | ===================
1151 | 
1152 |   * deprecate `verify` option to `json` -- use `body-parser` npm module instead
1153 |   * deprecate `verify` option to `urlencoded` -- use `body-parser` npm module instead
1154 |   * deprecate things with `depd` module
1155 |   * use `finalhandler` for final response handling
1156 |   * use `media-typer` to parse `content-type` for charset
1157 |   * deps: body-parser@1.4.2
1158 |     - check accepted charset in content-type (accepts utf-8)
1159 |     - check accepted encoding in content-encoding (accepts identity)
1160 |     - deprecate `urlencoded()` without provided `extended` option
1161 |     - lazy-load urlencoded parsers
1162 |     - support gzip and deflate bodies
1163 |     - set `inflate: false` to turn off
1164 |     - deps: raw-body@1.2.2
1165 |     - deps: type-is@1.3.0
1166 |     - Support all encodings from `iconv-lite`
1167 |   * deps: connect-timeout@1.1.1
1168 |     - deps: debug@1.0.2
1169 |   * deps: cookie-parser@1.3.1
1170 |     - export parsing functions
1171 |     - `req.cookies` and `req.signedCookies` are now plain objects
1172 |     - slightly faster parsing of many cookies
1173 |   * deps: csurf@1.2.2
1174 |   * deps: errorhandler@1.1.0
1175 |     - Display error on console formatted like `throw`
1176 |     - Escape HTML in stack trace
1177 |     - Escape HTML in title
1178 |     - Fix up edge cases with error sent in response
1179 |     - Set `X-Content-Type-Options: nosniff` header
1180 |     - Use accepts for negotiation
1181 |   * deps: express-session@1.4.0
1182 |     - Add `genid` option to generate custom session IDs
1183 |     - Add `saveUninitialized` option to control saving uninitialized sessions
1184 |     - Add `unset` option to control unsetting `req.session`
1185 |     - Generate session IDs with `rand-token` by default; reduce collisions
1186 |     - Integrate with express "trust proxy" by default
1187 |     - deps: buffer-crc32@0.2.3
1188 |     - deps: debug@1.0.2
1189 |   * deps: multiparty@3.2.9
1190 |   * deps: serve-index@1.1.2
1191 |     - deps: batch@0.5.1
1192 |   * deps: type-is@1.3.0
1193 |     - improve type parsing
1194 |   * deps: vhost@2.0.0
1195 |     - Accept `RegExp` object for `hostname`
1196 |     - Provide `req.vhost` object
1197 |     - Support IPv6 literal in `Host` header
1198 | 
1199 | 2.19.6 / 2014-06-11
1200 | ===================
1201 | 
1202 |   * deps: body-parser@1.3.1
1203 |     - deps: type-is@1.2.1
1204 |   * deps: compression@1.0.7
1205 |     - use vary module for better `Vary` behavior
1206 |     - deps: accepts@1.0.3
1207 |     - deps: compressible@1.1.0
1208 |   * deps: debug@1.0.2
1209 |   * deps: serve-index@1.1.1
1210 |     - deps: accepts@1.0.3
1211 |   * deps: serve-static@1.2.3
1212 |     - Do not throw un-catchable error on file open race condition
1213 |     - deps: send@0.4.3
1214 | 
1215 | 2.19.5 / 2014-06-09
1216 | ===================
1217 | 
1218 |   * deps: csurf@1.2.1
1219 |     - refactor to use csrf-tokens@~1.0.2
1220 |   * deps: debug@1.0.1
1221 |   * deps: serve-static@1.2.2
1222 |     - fix "event emitter leak" warnings
1223 |     - deps: send@0.4.2
1224 |   * deps: type-is@1.2.1
1225 |     - Switch dependency from `mime` to `mime-types@1.0.0`
1226 | 
1227 | 2.19.4 / 2014-06-05
1228 | ===================
1229 | 
1230 |   * deps: errorhandler@1.0.2
1231 |     - Pass on errors from reading error files
1232 |   * deps: method-override@2.0.2
1233 |     - use vary module for better `Vary` behavior
1234 |   * deps: serve-favicon@2.0.1
1235 |     - Reduce byte size of `ETag` header
1236 | 
1237 | 2.19.3 / 2014-06-03
1238 | ===================
1239 | 
1240 |   * deps: compression@1.0.6
1241 |     - fix listeners for delayed stream creation
1242 |     - fix regression for certain `stream.pipe(res)` situations
1243 |     - fix regression when negotiation fails
1244 | 
1245 | 2.19.2 / 2014-06-03
1246 | ===================
1247 | 
1248 |   * deps: compression@1.0.4
1249 |     - fix adding `Vary` when value stored as array
1250 |     - fix back-pressure behavior
1251 |     - fix length check for `res.end`
1252 | 
1253 | 2.19.1 / 2014-06-02
1254 | ===================
1255 | 
1256 |   * fix deprecated `utils.escape`
1257 | 
1258 | 2.19.0 / 2014-06-02
1259 | ===================
1260 | 
1261 |   * deprecate `methodOverride()` -- use `method-override` npm module instead
1262 |   * deps: body-parser@1.3.0
1263 |     - add `extended` option to urlencoded parser
1264 |   * deps: method-override@2.0.1
1265 |     - set `Vary` header
1266 |     - deps: methods@1.0.1
1267 |   * deps: multiparty@3.2.8
1268 |   * deps: response-time@2.0.0
1269 |     - add `digits` argument
1270 |     - do not override existing `X-Response-Time` header
1271 |     - timer not subject to clock drift
1272 |     - timer resolution down to nanoseconds
1273 |   * deps: serve-static@1.2.1
1274 |     - send max-age in Cache-Control in correct format
1275 |     - use `escape-html` for escaping
1276 |     - deps: send@0.4.1
1277 | 
1278 | 2.18.0 / 2014-05-29
1279 | ===================
1280 | 
1281 |   * deps: compression@1.0.3
1282 |   * deps: serve-index@1.1.0
1283 |     - Fix content negotiation when no `Accept` header
1284 |     - Properly support all HTTP methods
1285 |     - Support vanilla node.js http servers
1286 |     - Treat `ENAMETOOLONG` as code 414
1287 |     - Use accepts for negotiation
1288 |   * deps: serve-static@1.2.0
1289 |     - Calculate ETag with md5 for reduced collisions
1290 |     - Fix wrong behavior when index file matches directory
1291 |     - Ignore stream errors after request ends
1292 |     - Skip directories in index file search
1293 |     - deps: send@0.4.0
1294 | 
1295 | 2.17.3 / 2014-05-27
1296 | ===================
1297 | 
1298 |   * deps: express-session@1.2.1
1299 |     - Fix `resave` such that `resave: true` works
1300 | 
1301 | 2.17.2 / 2014-05-27
1302 | ===================
1303 | 
1304 |   * deps: body-parser@1.2.2
1305 |     - invoke `next(err)` after request fully read
1306 |     - deps: raw-body@1.1.6
1307 |   * deps: method-override@1.0.2
1308 |     - Handle `req.body` key referencing array or object
1309 |     - Handle multiple HTTP headers
1310 | 
1311 | 2.17.1 / 2014-05-21
1312 | ===================
1313 | 
1314 |   * fix `res.charset` appending charset when `content-type` has one
1315 | 
1316 | 2.17.0 / 2014-05-20
1317 | ===================
1318 | 
1319 |   * deps: express-session@1.2.0
1320 |     - Add `resave` option to control saving unmodified sessions
1321 |   * deps: morgan@1.1.1
1322 |     - "dev" format will use same tokens as other formats
1323 |     - `:response-time` token is now empty when immediate used
1324 |     - `:response-time` token is now monotonic
1325 |     - `:response-time` token has precision to 1 μs
1326 |     - fix `:status` + immediate output in node.js 0.8
1327 |     - improve `buffer` option to prevent indefinite event loop holding
1328 |     - simplify method to get remote address
1329 |     - deps: bytes@1.0.0
1330 |   * deps: serve-index@1.0.3
1331 |     - Fix error from non-statable files in HTML view
1332 | 
1333 | 2.16.2 / 2014-05-18
1334 | ===================
1335 | 
1336 |   * fix edge-case in `res.appendHeader` that would append in wrong order
1337 |   * deps: method-override@1.0.1
1338 | 
1339 | 2.16.1 / 2014-05-17
1340 | ===================
1341 | 
1342 |   * remove usages of `res.headerSent` from core
1343 | 
1344 | 2.16.0 / 2014-05-17
1345 | ===================
1346 | 
1347 |   * deprecate `res.headerSent` -- use `res.headersSent`
1348 |   * deprecate `res.on("header")` -- use on-headers module instead
1349 |   * fix `connect.version` to reflect the actual version
1350 |   * json: use body-parser
1351 |     - add `type` option
1352 |     - fix repeated limit parsing with every request
1353 |     - improve parser speed
1354 |   * urlencoded: use body-parser
1355 |     - add `type` option
1356 |     - fix repeated limit parsing with every request
1357 |   * dep: bytes@1.0.0
1358 |     * add negative support
1359 |   * dep: cookie-parser@1.1.0
1360 |     - deps: cookie@0.1.2
1361 |   * dep: csurf@1.2.0
1362 |     - add support for double-submit cookie
1363 |   * dep: express-session@1.1.0
1364 |     - Add `name` option; replacement for `key` option
1365 |     - Use `setImmediate` in MemoryStore for node.js >= 0.10
1366 | 
1367 | 2.15.0 / 2014-05-04
1368 | ===================
1369 | 
1370 |   * Add simple `res.cookie` support
1371 |   * Add `res.appendHeader`
1372 |   * Call error stack even when response has been sent
1373 |   * Patch `res.headerSent` to return Boolean
1374 |   * Patch `res.headersSent` for node.js 0.8
1375 |   * Prevent default 404 handler after response sent
1376 |   * dep: compression@1.0.2
1377 |     * support headers given to `res.writeHead`
1378 |     * deps: bytes@0.3.0
1379 |     * deps: negotiator@0.4.3
1380 |   * dep: connect-timeout@1.1.0
1381 |     * Add `req.timedout` property
1382 |     * Add `respond` option to constructor
1383 |     * Clear timer on socket destroy
1384 |     * deps: debug@0.8.1
1385 |   * dep: debug@^0.8.0
1386 |     * add `enable()` method
1387 |     * change from stderr to stdout
1388 |   * dep: errorhandler@1.0.1
1389 |     * Clean up error CSS
1390 |     * Do not respond after headers sent
1391 |   * dep: express-session@1.0.4
1392 |     * Remove import of `setImmediate`
1393 |     * Use `res.cookie()` instead of `res.setHeader()`
1394 |     * deps: cookie@0.1.2
1395 |     * deps: debug@0.8.1
1396 |   * dep: morgan@1.0.1
1397 |     * Make buffer unique per morgan instance
1398 |     * deps: bytes@0.3.0
1399 |   * dep: serve-favicon@2.0.0
1400 |     * Accept `Buffer` of icon as first argument
1401 |     * Non-GET and HEAD requests are denied
1402 |     * Send valid max-age value
1403 |     * Support conditional requests
1404 |     * Support max-age=0
1405 |     * Support OPTIONS method
1406 |     * Throw if `path` argument is directory
1407 |   * dep: serve-index@1.0.2
1408 |     * Add stylesheet option
1409 |     * deps: negotiator@0.4.3
1410 | 
1411 | 2.14.5 / 2014-04-24
1412 | ===================
1413 | 
1414 |   * dep: raw-body@1.1.4
1415 |     * allow true as an option
1416 |     * deps: bytes@0.3.0
1417 |   * dep: serve-static@1.1.0
1418 |     * Accept options directly to `send` module
1419 |     * deps: send@0.3.0
1420 | 
1421 | 2.14.4 / 2014-04-07
1422 | ===================
1423 | 
1424 |   * dep: bytes@0.3.0
1425 |     * added terabyte support
1426 |   * dep: csurf@1.1.0
1427 |     * add constant-time string compare
1428 |   * dep: serve-static@1.0.4
1429 |     * Resolve relative paths at middleware setup
1430 |     * Use parseurl to parse the URL from request
1431 |   * fix node.js 0.8 compatibility with memory session
1432 | 
1433 | 2.14.3 / 2014-03-18
1434 | ===================
1435 | 
1436 |   * dep: static-favicon@1.0.2
1437 |     * Fixed content of default icon
1438 | 
1439 | 2.14.2 / 2014-03-11
1440 | ===================
1441 | 
1442 |   * dep: static-favicon@1.0.1
1443 |     * Fixed path to default icon
1444 | 
1445 | 2.14.1 / 2014-03-06
1446 | ===================
1447 | 
1448 |   * dep: fresh@0.2.2
1449 |     * no real changes
1450 |   * dep: serve-index@1.0.1
1451 |     * deps: negotiator@0.4.2
1452 |   * dep: serve-static@1.0.2
1453 |     * deps: send@0.2.0
1454 | 
1455 | 2.14.0 / 2014-03-05
1456 | ===================
1457 | 
1458 |  * basicAuth: use basic-auth-connect
1459 |  * cookieParser: use cookie-parser
1460 |  * compress: use compression
1461 |  * csrf: use csurf
1462 |  * dep: cookie-signature@1.0.3
1463 |  * directory: use serve-index
1464 |  * errorHandler: use errorhandler
1465 |  * favicon: use static-favicon
1466 |  * logger: use morgan
1467 |  * methodOverride: use method-override
1468 |  * responseTime: use response-time
1469 |  * session: use express-session
1470 |  * static: use serve-static
1471 |  * timeout: use connect-timeout
1472 |  * vhost: use vhost
1473 | 
1474 | 2.13.1 / 2014-03-05
1475 | ===================
1476 | 
1477 |  * cookieSession: compare full value rather than crc32
1478 |  * deps: raw-body@1.1.3
1479 | 
1480 | 2.13.0 / 2014-02-14
1481 | ===================
1482 | 
1483 |  * fix typo in memory store warning #974 @rvagg
1484 |  * compress: use compressible
1485 |  * directory: add template option #990 @gottaloveit @Earl-Brown
1486 |  * csrf: prevent deprecated warning with old sessions
1487 | 
1488 | 2.12.0 / 2013-12-10
1489 | ===================
1490 | 
1491 |  * bump qs
1492 |  * directory: sort folders before files
1493 |  * directory: add folder icons
1494 |  * directory: de-duplicate icons, details/mobile views #968 @simov
1495 |  * errorHandler: end default 404 handler with a newline #972 @rlidwka
1496 |  * session: remove long cookie expire check #870 @undoZen
1497 | 
1498 | 2.11.2 / 2013-12-01
1499 | ===================
1500 | 
1501 |  * bump raw-body
1502 | 
1503 | 2.11.1 / 2013-11-27
1504 | ===================
1505 | 
1506 |  * bump raw-body
1507 |  * errorHandler: use `res.setHeader()` instead of `res.writeHead()` #949 @lo1tuma
1508 | 
1509 | 2.11.0 / 2013-10-29
1510 | ===================
1511 | 
1512 |  * update bytes
1513 |  * update uid2
1514 |  * update negotiator
1515 |  * sessions: add rolling session option #944 @ilmeo
1516 |  * sessions: property set cookies when given FQDN
1517 |  * cookieSessions: properly set cookies when given FQDN #948 @bmancini55
1518 |  * proto: fix FQDN mounting when multiple handlers #945 @bmancini55
1519 | 
1520 | 2.10.1 / 2013-10-23
1521 | ===================
1522 | 
1523 |  * fixed; fixed a bug with static middleware at root and trailing slashes #942 (@dougwilson)
1524 | 
1525 | 2.10.0 / 2013-10-22
1526 | ===================
1527 | 
1528 |  * fixed: set headers written by writeHead before emitting 'header'
1529 |  * fixed: mounted path should ignore querystrings on FQDNs #940 (@dougwilson)
1530 |  * fixed: parsing protocol-relative URLs with @ as pathnames #938 (@dougwilson)
1531 |  * fixed: fix static directory redirect for mount's root #937 (@dougwilson)
1532 |  * fixed: setting set-cookie header when mixing arrays and strings #893 (@anuj123)
1533 |  * bodyParser: optional verify function for urlencoded and json parsers for signing request bodies
1534 |  * compress: compress checks content-length to check threshold
1535 |  * compress: expose `res.flush()` for flushing responses
1536 |  * cookieParser: pass options into node-cookie #803 (@cauldrath)
1537 |  * errorHandler: replace `\n`s with `<br/>`s in error handler
1538 | 
1539 | 2.9.2 / 2013-10-18
1540 | ==================
1541 | 
1542 |  * warn about multiparty and limit middleware deprecation for v3
1543 |  * fix fully qualified domain name mounting. #920 (@dougwilson)
1544 |  * directory: Fix potential security issue with serving files outside the root. #929 (@dougwilson)
1545 |  * logger: store IP at beginning in case socket prematurely closes #930 (@dougwilson)
1546 | 
1547 | 2.9.1 / 2013-10-15
1548 | ==================
1549 | 
1550 |  * update multiparty
1551 |  * compress: Set vary header only if Content-Type passes filter #904
1552 |  * directory: Fix directory middleware URI escaping #917 (@dougwilson)
1553 |  * directory: Fix directory seperators for Windows #914 (@dougwilson)
1554 |  * directory: Keep query string intact during directory redirect #913 (@dougwilson)
1555 |  * directory: Fix paths in links #730 (@JacksonTian)
1556 |  * errorHandler: Don't escape text/plain as HTML #875 (@johan)
1557 |  * logger: Write '0' instead of '-' when response time is zero #910 (@dougwilson)
1558 |  * logger: Log even when connections are aborted #760 (@dylanahsmith)
1559 |  * methodOverride: Check req.body is an object #907 (@kbjr)
1560 |  * multipart: Add .type back to file parts for backwards compatibility #912 (@dougwilson)
1561 |  * multipart: Allow passing options to the Multiparty constructor #902 (@niftylettuce)
1562 | 
1563 | 2.9.0 / 2013-09-07
1564 | ==================
1565 | 
1566 |  * multipart: add docs regarding tmpfiles
1567 |  * multipart: add .name back to file parts
1568 |  * multipart: use multiparty instead of formidable
1569 | 
1570 | 2.8.8 / 2013-09-02
1571 | ==================
1572 | 
1573 |  * csrf: change to math.random() salt and remove csrfToken() callback
1574 | 
1575 | 2.8.7 / 2013-08-28
1576 | ==================
1577 | 
1578 |  * csrf: prevent salt generation on every request, and add async req.csrfToken(fn)
1579 | 
1580 | 2.8.6 / 2013-08-28
1581 | ==================
1582 | 
1583 |  * csrf: refactor to use HMAC tokens (BREACH attack)
1584 |  * compress: add compression of SVG and common font files by default.
1585 | 
1586 | 2.8.5 / 2013-08-11
1587 | ==================
1588 | 
1589 |  * add: compress Dart source files by default
1590 |  * update fresh
1591 | 
1592 | 2.8.4 / 2013-07-08
1593 | ==================
1594 | 
1595 |  * update send
1596 | 
1597 | 2.8.3 / 2013-07-04
1598 | ==================
1599 | 
1600 |  * add a name back to static middleware ("staticMiddleware")
1601 |  * fix .hasBody() utility to require transfer-encoding or content-length
1602 | 
1603 | 2.8.2 / 2013-07-03
1604 | ==================
1605 | 
1606 |  * update send
1607 |  * update cookie dep.
1608 |  * add better debug() for middleware
1609 |  * add whitelisting of supported methods to methodOverride()
1610 | 
1611 | 2.8.1 / 2013-06-27
1612 | ==================
1613 | 
1614 |  * fix: escape req.method in 404 response
1615 | 
1616 | 2.8.0 / 2013-06-26
1617 | ==================
1618 | 
1619 |  * add `threshold` option to `compress()` to prevent compression of small responses
1620 |  * add support for vendor JSON mime types in json()
1621 |  * add X-Forwarded-Proto initial https proxy support
1622 |  * change static redirect to 303
1623 |  * change octal escape sequences for strict mode
1624 |  * change: replace utils.uid() with uid2 lib
1625 |  * remove other "static" function name. Fixes #794
1626 |  * fix: hasBody() should return false if Content-Length: 0
1627 | 
1628 | 2.7.11 / 2013-06-02
1629 | ==================
1630 | 
1631 |  * update send
1632 | 
1633 | 2.7.10 / 2013-05-21
1634 | ==================
1635 | 
1636 |  * update qs
1637 |  * update formidable
1638 |  * fix: write/end to noop() when request aborted
1639 | 
1640 | 2.7.9 / 2013-05-07
1641 | ==================
1642 | 
1643 |   * update qs
1644 |   * drop support for node < v0.8
1645 | 
1646 | 2.7.8 / 2013-05-03
1647 | ==================
1648 | 
1649 |   * update qs
1650 | 
1651 | 2.7.7 / 2013-04-29
1652 | ==================
1653 | 
1654 |   * update qs dependency
1655 |   * remove "static" function name. Closes #794
1656 |   * update node-formidable
1657 |   * update buffer-crc32
1658 | 
1659 | 2.7.6 / 2013-04-15
1660 | ==================
1661 | 
1662 |   * revert cookie signature which was creating session race conditions
1663 | 
1664 | 2.7.5 / 2013-04-12
1665 | ==================
1666 | 
1667 |   * update cookie-signature
1668 |   * limit: do not consume request in node 0.10.x
1669 | 
1670 | 2.7.4 / 2013-04-01
1671 | ==================
1672 | 
1673 |   * session: add long expires check and prevent excess set-cookie
1674 |   * session: add console.error() of session#save() errors
1675 | 
1676 | 2.7.3 / 2013-02-19
1677 | ==================
1678 | 
1679 |   * add name to compress middleware
1680 |   * add appending Accept-Encoding to Vary when set but missing
1681 |   * add tests for csrf middleware
1682 |   * add 'next' support for connect() server handler
1683 |   * change utils.uid() to return url-safe chars. Closes #753
1684 |   * fix treating '.' as a regexp in vhost()
1685 |   * fix duplicate bytes dep in package.json. Closes #743
1686 |   * fix #733 - parse x-forwarded-proto in a more generally compatibly way
1687 |   * revert "add support for `next(status[, msg])`"; makes composition hard
1688 | 
1689 | 2.7.2 / 2013-01-04
1690 | ==================
1691 | 
1692 |   * add support for `next(status[, msg])` back
1693 |   * add utf-8 meta tag to support foreign characters in filenames/directories
1694 |   * change `timeout()` 408 to 503
1695 |   * replace 'node-crc' with 'buffer-crc32', fixes licensing
1696 |   * fix directory.html IE support
1697 | 
1698 | 2.7.1 / 2012-12-05
1699 | ==================
1700 | 
1701 |   * add directory() tests
1702 |   * add support for bodyParser to ignore Content-Type if no body is present (jquery primarily does this poorely)
1703 |   * fix errorHandler signature
1704 | 
1705 | 2.7.0 / 2012-11-13
1706 | ==================
1707 | 
1708 |   * add support for leading JSON whitespace
1709 |   * add logging of `req.ip` when present
1710 |   * add basicAuth support for `:`-delimited string
1711 |   * update cookie module. Closes #688
1712 | 
1713 | 2.6.2 / 2012-11-01
1714 | ==================
1715 | 
1716 |   * add `debug()` for disconnected session store
1717 |   * fix session regeneration bug. Closes #681
1718 | 
1719 | 2.6.1 / 2012-10-25
1720 | ==================
1721 | 
1722 |   * add passing of `connect.timeout()` errors to `next()`
1723 |   * replace signature utils with cookie-signature module
1724 | 
1725 | 2.6.0 / 2012-10-09
1726 | ==================
1727 | 
1728 |   * add `defer` option to `multipart()` [Blake Miner]
1729 |   * fix mount path case sensitivity. Closes #663
1730 |   * fix default of ascii encoding from `logger()`, now utf8. Closes #293
1731 | 
1732 | 2.5.0 / 2012-09-27
1733 | ==================
1734 | 
1735 |   * add `err.status = 400` to multipart() errors
1736 |   * add double-encoding protection to `compress()`. Closes #659
1737 |   * add graceful handling cookie parsing errors [shtylman]
1738 |   * fix typo X-Response-time to X-Response-Time
1739 | 
1740 | 2.4.6 / 2012-09-18
1741 | ==================
1742 | 
1743 |   * update qs
1744 | 
1745 | 2.4.5 / 2012-09-03
1746 | ==================
1747 | 
1748 |   * add session store "connect" / "disconnect" support [louischatriot]
1749 |   * fix `:url` log token
1750 | 
1751 | 2.4.4 / 2012-08-21
1752 | ==================
1753 | 
1754 |   * fix `static()` pause regression from "send" integration
1755 | 
1756 | 2.4.3 / 2012-08-07
1757 | ==================
1758 | 
1759 |   * fix `.write()` encoding for zlib inconstancy. Closes #561
1760 | 
1761 | 2.4.2 / 2012-07-25
1762 | ==================
1763 | 
1764 |   * remove limit default from `urlencoded()`
1765 |   * remove limit default from `json()`
1766 |   * remove limit default from `multipart()`
1767 |   * fix `cookieSession()` clear cookie path / domain bug. Closes #636
1768 | 
1769 | 2.4.1 / 2012-07-24
1770 | ==================
1771 | 
1772 |   * fix `options` mutation in `static()`
1773 | 
1774 | 2.4.0 / 2012-07-23
1775 | ==================
1776 | 
1777 |   * add `connect.timeout()`
1778 |   * add __GET__ / __HEAD__ check to `directory()`. Closes #634
1779 |   * add "pause" util dep
1780 |   * update send dep for normalization bug
1781 | 
1782 | 2.3.9 / 2012-07-16
1783 | ==================
1784 | 
1785 |   * add more descriptive invalid json error message
1786 |   * update send dep for root normalization regression
1787 |   * fix staticCache fresh dep
1788 | 
1789 | 2.3.8 / 2012-07-12
1790 | ==================
1791 | 
1792 |   * fix `connect.static()` 404 regression, pass `next()`. Closes #629
1793 | 
1794 | 2.3.7 / 2012-07-05
1795 | ==================
1796 | 
1797 |   * add `json()` utf-8 illustration test. Closes #621
1798 |   * add "send" dependency
1799 |   * change `connect.static()` internals to use "send"
1800 |   * fix `session()` req.session generation with pathname mismatch
1801 |   * fix `cookieSession()` req.session generation with pathname mismatch
1802 |   * fix mime export. Closes #618
1803 | 
1804 | 2.3.6 / 2012-07-03
1805 | ==================
1806 | 
1807 |   * Fixed cookieSession() with cookieParser() secret regression. Closes #602
1808 |   * Fixed set-cookie header fields on cookie.path mismatch. Closes #615
1809 | 
1810 | 2.3.5 / 2012-06-28
1811 | ==================
1812 | 
1813 |   * Remove `logger()` mount check
1814 |   * Fixed `staticCache()` dont cache responses with set-cookie. Closes #607
1815 |   * Fixed `staticCache()` when Cookie is present
1816 | 
1817 | 2.3.4 / 2012-06-22
1818 | ==================
1819 | 
1820 |   * Added `err.buf` to urlencoded() and json()
1821 |   * Update cookie to 0.0.4. Closes #604
1822 |   * Fixed: only send 304 if original response in 2xx or 304 [timkuijsten]
1823 | 
1824 | 2.3.3 / 2012-06-11
1825 | ==================
1826 | 
1827 |   * Added ETags back to `static()` [timkuijsten]
1828 |   * Replaced `utils.parseRange()` with `range-parser` module
1829 |   * Replaced `utils.parseBytes()` with `bytes` module
1830 |   * Replaced `utils.modified()` with `fresh` module
1831 |   * Fixed `cookieSession()` regression with invalid cookie signing [shtylman]
1832 | 
1833 | 2.3.2 / 2012-06-08
1834 | ==================
1835 | 
1836 |   * expose mime module
1837 |   * Update crc dep (which bundled nodeunit)
1838 | 
1839 | 2.3.1 / 2012-06-06
1840 | ==================
1841 | 
1842 |   * Added `secret` option to `cookieSession` middleware [shtylman]
1843 |   * Added `secret` option to `session` middleware [shtylman]
1844 |   * Added `req.remoteUser` back to `basicAuth()` as alias of `req.user`
1845 |   * Performance: improve signed cookie parsing
1846 |   * Update `cookie` dependency [shtylman]
1847 | 
1848 | 2.3.0 / 2012-05-20
1849 | ==================
1850 | 
1851 |   * Added limit option to `json()`
1852 |   * Added limit option to `urlencoded()`
1853 |   * Added limit option to `multipart()`
1854 |   * Fixed: remove socket error event listener on callback
1855 |   * Fixed __ENOTDIR__ error on `static` middleware
1856 | 
1857 | 2.2.2 / 2012-05-07
1858 | ==================
1859 | 
1860 |   * Added support to csrf middle for pre-flight CORS requests
1861 |   * Updated `engines` to allow newer version of node
1862 |   * Removed duplicate repo prop. Closes #560
1863 | 
1864 | 2.2.1 / 2012-04-28
1865 | ==================
1866 | 
1867 |   * Fixed `static()` redirect when mounted. Closes #554
1868 | 
1869 | 2.2.0 / 2012-04-25
1870 | ==================
1871 | 
1872 |   * Added `make benchmark`
1873 |   * Perf: memoize url parsing (~20% increase)
1874 |   * Fixed `connect(fn, fn2, ...)`. Closes #549
1875 | 
1876 | 2.1.3 / 2012-04-20
1877 | ==================
1878 | 
1879 |   * Added optional json() `reviver` function to be passed to JSON.parse [jed]
1880 |   * Fixed: emit drain in compress middleware [nsabovic]
1881 | 
1882 | 2.1.2 / 2012-04-11
1883 | ==================
1884 | 
1885 |   * Fixed cookieParser() `req.cookies` regression
1886 | 
1887 | 2.1.1 / 2012-04-11
1888 | ==================
1889 | 
1890 |   * Fixed `session()` browser-session length cookies & examples
1891 |   * Fixed: make `query()` "self-aware" [jed]
1892 | 
1893 | 2.1.0 / 2012-04-05
1894 | ==================
1895 | 
1896 |   * Added `debug()` calls to `.use()` (`DEBUG=connect:displatcher`)
1897 |   * Added `urlencoded()` support for GET
1898 |   * Added `json()` support for GET. Closes #497
1899 |   * Added `strict` option to `json()`
1900 |   * Changed: `session()` only set-cookie when modified
1901 |   * Removed `Session#lastAccess` property. Closes #399
1902 | 
1903 | 2.0.3 / 2012-03-20
1904 | ==================
1905 | 
1906 |   * Added: `cookieSession()` only sets cookie on change. Closes #442
1907 |   * Added `connect:dispatcher` debug() probes
1908 | 
1909 | 2.0.2 / 2012-03-04
1910 | ==================
1911 | 
1912 |   * Added test for __ENAMETOOLONG__ now that node is fixed
1913 |   * Fixed static() index "/" check on windows. Closes #498
1914 |   * Fixed Content-Range behaviour to match RFC2616 [matthiasdg / visionmedia]
1915 | 
1916 | 2.0.1 / 2012-02-29
1917 | ==================
1918 | 
1919 |   * Added test coverage for `vhost()` middleware
1920 |   * Changed `cookieParser()` signed cookie support to use SHA-2 [senotrusov]
1921 |   * Fixed `static()` Range: respond with 416 when unsatisfiable
1922 |   * Fixed `vhost()` middleware. Closes #494
1923 | 
1924 | 2.0.0 / 2011-10-05
1925 | ==================
1926 | 
1927 |   * Added `cookieSession()` middleware for cookie-only sessions
1928 |   * Added `compress()` middleware for gzip / deflate support
1929 |   * Added `session()` "proxy" setting to trust `X-Forwarded-Proto`
1930 |   * Added `json()` middleware to parse "application/json"
1931 |   * Added `urlencoded()` middleware to parse "application/x-www-form-urlencoded"
1932 |   * Added `multipart()` middleware to parse "multipart/form-data"
1933 |   * Added `cookieParser(secret)` support so anything using this middleware may access signed cookies
1934 |   * Added signed cookie support to `cookieParser()`
1935 |   * Added support for JSON-serialized cookies to `cookieParser()`
1936 |   * Added `err.status` support in Connect's default end-point
1937 |   * Added X-Cache MISS / HIT to `staticCache()`
1938 |   * Added public `res.headerSent` checking nodes `res._headerSent` until node does
1939 |   * Changed `basicAuth()` req.remoteUser to req.user
1940 |   * Changed: default `session()` to a browser-session cookie. Closes #475
1941 |   * Changed: no longer lowercase cookie names
1942 |   * Changed `bodyParser()` to use `json()`, `urlencoded()`, and `multipart()`
1943 |   * Changed: `errorHandler()` is now a development-only middleware
1944 |   * Changed middleware to `next()` errors when possible so applications can unify logging / handling
1945 |   * Removed `http[s].Server` inheritance, now just a function, making it easy to have an app providing both http and https
1946 |   * Removed `.createServer()` (use `connect()`)
1947 |   * Removed `secret` option from `session()`, use `cookieParser(secret)`
1948 |   * Removed `connect.session.ignore` array support
1949 |   * Removed `router()` middleware. Closes #262
1950 |   * Fixed: set-cookie only once for browser-session cookies
1951 |   * Fixed FQDN support. dont add leading "/"
1952 |   * Fixed 404 XSS attack vector. Closes #473
1953 |   * Fixed __HEAD__ support for 404s and 500s generated by Connect's end-point
1954 | 
1955 | 1.8.5 / 2011-12-22
1956 | ==================
1957 | 
1958 |   * Fixed: actually allow empty body for json
1959 | 
1960 | 1.8.4 / 2011-12-22
1961 | ==================
1962 | 
1963 |   * Changed: allow empty body for json/urlencoded requests. Backport for #443
1964 | 
1965 | 1.8.3 / 2011-12-16
1966 | ==================
1967 | 
1968 |   * Fixed `static()` _index.html_ support on windows
1969 | 
1970 | 1.8.2 / 2011-12-03
1971 | ==================
1972 | 
1973 |   * Fixed potential security issue, store files in req.files. Closes #431 [reported by dobesv]
1974 | 
1975 | 1.8.1 / 2011-11-21
1976 | ==================
1977 | 
1978 |   * Added nesting support for _multipart/form-data_ [jackyz]
1979 | 
1980 | 1.8.0 / 2011-11-17
1981 | ==================
1982 | 
1983 |   * Added _multipart/form-data_ support to `bodyParser()` using formidable
1984 | 
1985 | 1.7.3 / 2011-11-11
1986 | ==================
1987 | 
1988 |   * Fixed `req.body`, always default to {}
1989 |   * Fixed HEAD support for 404s and 500s
1990 | 
1991 | 1.7.2 / 2011-10-24
1992 | ==================
1993 | 
1994 |   * "node": ">= 0.4.1 < 0.7.0"
1995 |   * Added `static()` redirect option. Closes #398
1996 |   * Changed `limit()`: respond with 413 when content-length exceeds the limit
1997 |   * Removed socket error listener in static(). Closes #389
1998 |   * Fixed `staticCache()` Age header field
1999 |   * Fixed race condition causing errors reported in #329.
2000 | 
2001 | 1.7.1 / 2011-09-12
2002 | ==================
2003 | 
2004 |   * Added: make `Store` inherit from `EventEmitter`
2005 |   * Added session `Store#load(sess, fn)` to fetch a `Session` instance
2006 |   * Added backpressure support to `staticCache()`
2007 |   * Changed `res.socket.destroy()` to `req.socket.destroy()`
2008 | 
2009 | 1.7.0 / 2011-08-31
2010 | ==================
2011 | 
2012 |   * Added `staticCache()` middleware, a memory cache for `static()`
2013 |   * Added public `res.headerSent` checking nodes `res._headerSent` (remove when node adds this)
2014 |   * Changed: ignore error handling middleware when header is sent
2015 |   * Changed: dispatcher errors after header is sent destroy the sock
2016 | 
2017 | 1.6.4 / 2011-08-26
2018 | ==================
2019 | 
2020 |   * Revert "Added double-next reporting"
2021 | 
2022 | 1.6.3 / 2011-08-26
2023 | ==================
2024 | 
2025 |   * Added double-`next()` reporting
2026 |   * Added `immediate` option to `logger()`. Closes #321
2027 |   * Dependency `qs >= 0.3.1`
2028 | 
2029 | 1.6.2 / 2011-08-11
2030 | ==================
2031 | 
2032 |   * Fixed `connect.static()` null byte vulnerability
2033 |   * Fixed `connect.directory()` null byte vulnerability
2034 |   * Changed: 301 redirect in `static()` to postfix "/" on directory. Closes #289
2035 | 
2036 | 1.6.1 / 2011-08-03
2037 | ==================
2038 | 
2039 |   * Added: allow retval `== null` from logger callback to ignore line
2040 |   * Added `getOnly` option to `connect.static.send()`
2041 |   * Added response "header" event allowing augmentation
2042 |   * Added `X-CSRF-Token` header field check
2043 |   * Changed dep `qs >= 0.3.0`
2044 |   * Changed: persist csrf token. Closes #322
2045 |   * Changed: sort directory middleware files alphabetically
2046 | 
2047 | 1.6.0 / 2011-07-10
2048 | ==================
2049 | 
2050 |   * Added :response-time to "dev" logger format
2051 |   * Added simple `csrf()` middleware. Closes #315
2052 |   * Fixed `res._headers` logger regression. Closes #318
2053 |   * Removed support for multiple middleware being passed to `.use()`
2054 | 
2055 | 1.5.2 / 2011-07-06
2056 | ==================
2057 | 
2058 |   * Added `filter` function option to `directory()` [David Rio Deiros]
2059 |   * Changed: re-write of the `logger()` middleware, with extensible tokens and formats
2060 |   * Changed: `static.send()` ".." in path without root considered malicious
2061 |   * Fixed quotes in docs. Closes #312
2062 |   * Fixed urls when mounting `directory()`, use `originalUrl` [Daniel Dickison]
2063 | 
2064 | 
2065 | 1.5.1 / 2011-06-20
2066 | ==================
2067 | 
2068 |   * Added malicious path check to `directory()` middleware
2069 |   * Added `utils.forbidden(res)`
2070 |   * Added `connect.query()` middleware
2071 | 
2072 | 1.5.0 / 2011-06-20
2073 | ==================
2074 | 
2075 |   * Added `connect.directory()` middleware for serving directory listings
2076 | 
2077 | 1.4.6 / 2011-06-18
2078 | ==================
2079 | 
2080 |   * Fixed `connect.static()` root with `..`
2081 |   * Fixed `connect.static()` __EBADF__
2082 | 
2083 | 1.4.5 / 2011-06-17
2084 | ==================
2085 | 
2086 |   * Fixed EBADF in `connect.static()`. Closes #297
2087 | 
2088 | 1.4.4 / 2011-06-16
2089 | ==================
2090 | 
2091 |   * Changed `connect.static()` to check resolved dirname. Closes #294
2092 | 
2093 | 1.4.3 / 2011-06-06
2094 | ==================
2095 | 
2096 |   * Fixed fd leak in `connect.static()` when the socket is closed
2097 |   * Fixed; `bodyParser()` ignoring __GET/HEAD__. Closes #285
2098 | 
2099 | 1.4.2 / 2011-05-27
2100 | ==================
2101 | 
2102 |   * Changed to `devDependencies`
2103 |   * Fixed stream creation on `static()` __HEAD__ request. [Andreas Lind Petersen]
2104 |   * Fixed Win32 support for `static()`
2105 |   * Fixed monkey-patch issue. Closes #261
2106 | 
2107 | 1.4.1 / 2011-05-08
2108 | ==================
2109 | 
2110 |   * Added "hidden" option to `static()`. ignores hidden files by default. Closes   * Added; expose `connect.static.mime.define()`. Closes #251
2111 |   * Fixed `errorHandler` middleware for missing stack traces. [aseemk]
2112 | #274
2113 | 
2114 | 1.4.0 / 2011-04-25
2115 | ==================
2116 | 
2117 |   * Added route-middleware `next('route')` support to jump passed the route itself
2118 |   * Added Content-Length support to `limit()`
2119 |   * Added route-specific middleware support (used to be in express)
2120 |   * Changed; refactored duplicate session logic
2121 |   * Changed; prevent redefining `store.generate` per request
2122 |   * Fixed; `static()` does not set Content-Type when explicitly set [nateps]
2123 |   * Fixed escape `errorHandler()` {error} contents
2124 |   * NOTE: `router` will be removed in 2.0
2125 | 
2126 | 
2127 | 1.3.0 / 2011-04-06
2128 | ==================
2129 | 
2130 |   * Added `router.remove(path[, method])` to remove a route
2131 | 
2132 | 1.2.3 / 2011-04-05
2133 | ==================
2134 | 
2135 |   * Fixed basicAuth realm issue when passing strings. Closes #253
2136 | 
2137 | 1.2.2 / 2011-04-05
2138 | ==================
2139 | 
2140 |   * Added `basicAuth(username, password)` support
2141 |   * Added `errorHandler.title` defaulting to "Connect"
2142 |   * Changed `errorHandler` css
2143 | 
2144 | 1.2.1 / 2011-03-30
2145 | ==================
2146 | 
2147 |   * Fixed `logger()` https `remoteAddress` logging [Alexander Simmerl]
2148 | 
2149 | 1.2.0 / 2011-03-30
2150 | ==================
2151 | 
2152 |   * Added `router.lookup(path[, method])`
2153 |   * Added `router.match(url[, method])`
2154 |   * Added basicAuth async support. Closes #223
2155 | 
2156 | 1.1.5 / 2011-03-27
2157 | ==================
2158 | 
2159 |   * Added; allow `logger()` callback function to return an empty string to ignore logging
2160 |   * Fixed; utilizing `mime.charsets.lookup()` for `static()`. Closes 245
2161 | 
2162 | 1.1.4 / 2011-03-23
2163 | ==================
2164 | 
2165 |   * Added `logger()` support for format function
2166 |   * Fixed `logger()` to support mess of writeHead()/progressive api for node 0.4.x
2167 | 
2168 | 1.1.3 / 2011-03-21
2169 | ==================
2170 | 
2171 |   * Changed; `limit()` now calls `req.destroy()`
2172 | 
2173 | 1.1.2 / 2011-03-21
2174 | ==================
2175 | 
2176 |   * Added request "limit" event to `limit()` middleware
2177 |   * Changed; `limit()` middleware will `next(err)` on failure
2178 | 
2179 | 1.1.1 / 2011-03-18
2180 | ==================
2181 | 
2182 |   * Fixed session middleware for HTTPS. Closes #241 [reported by mt502]
2183 | 
2184 | 1.1.0 / 2011-03-17
2185 | ==================
2186 | 
2187 |   * Added `Session#reload(fn)`
2188 | 
2189 | 1.0.6 / 2011-03-09
2190 | ==================
2191 | 
2192 |   * Fixed `res.setHeader()` patch, preserve casing
2193 | 
2194 | 1.0.5 / 2011-03-09
2195 | ==================
2196 | 
2197 |   * Fixed; `logger()` using `req.originalUrl` instead of `req.url`
2198 | 
2199 | 1.0.4 / 2011-03-09
2200 | ==================
2201 | 
2202 |   * Added `res.charset`
2203 |   * Added conditional sessions example
2204 |   * Added support for `session.ignore` to be replaced. Closes #227
2205 |   * Fixed `Cache-Control` delimiters. Closes #228
2206 | 
2207 | 1.0.3 / 2011-03-03
2208 | ==================
2209 | 
2210 |   * Fixed; `static.send()` invokes callback with connection error
2211 | 
2212 | 1.0.2 / 2011-03-02
2213 | ==================
2214 | 
2215 |   * Fixed exported connect function
2216 |   * Fixed package.json; node ">= 0.4.1 < 0.5.0"
2217 | 
2218 | 1.0.1 / 2011-03-02
2219 | ==================
2220 | 
2221 |   * Added `Session#save(fn)`. Closes #213
2222 |   * Added callback support to `connect.static.send()` for express
2223 |   * Added `connect.static.send()` "path" option
2224 |   * Fixed content-type in `static()` for _index.html_
2225 | 
2226 | 1.0.0 / 2011-03-01
2227 | ==================
2228 | 
2229 |   * Added `stack`, `message`, and `dump` errorHandler option aliases
2230 |   * Added `req.originalMethod` to methodOverride
2231 |   * Added `favicon()` maxAge option support
2232 |   * Added `connect()` alternative to `connect.createServer()`
2233 |   * Added new [documentation](http://senchalabs.github.com/connect)
2234 |   * Added Range support to `static()`
2235 |   * Added HTTPS support
2236 |   * Rewrote session middleware. The session API now allows for
2237 |     session-specific cookies, so you may alter each individually.
2238 |     Click to view the new [session api](http://senchalabs.github.com/connect/middleware-session.html).
2239 |   * Added middleware self-awareness. This helps prevent
2240 |     middleware breakage when used within mounted servers.
2241 |     For example `cookieParser()` will not parse cookies more
2242 |     than once even when within a mounted server.
2243 |   * Added new examples in the `./examples` directory
2244 |   * Added [limit()](http://senchalabs.github.com/connect/middleware-limit.html) middleware
2245 |   * Added [profiler()](http://senchalabs.github.com/connect/middleware-profiler.html) middleware
2246 |   * Added [responseTime()](http://senchalabs.github.com/connect/middleware-responseTime.html) middleware
2247 |   * Renamed `staticProvider` to `static`
2248 |   * Renamed `bodyDecoder` to `bodyParser`
2249 |   * Renamed `cookieDecoder` to `cookieParser`
2250 |   * Fixed ETag quotes. [reported by papandreou]
2251 |   * Fixed If-None-Match comma-delimited ETag support. [reported by papandreou]
2252 |   * Fixed; only set req.originalUrl once. Closes #124
2253 |   * Fixed symlink support for `static()`. Closes #123
2254 | 
2255 | 0.5.10 / 2011-02-14
2256 | ==================
2257 | 
2258 |   * Fixed SID space issue. Closes #196
2259 |   * Fixed; proxy `res.end()` to commit session data
2260 |   * Fixed directory traversal attack in `staticProvider`. Closes #198
2261 | 
2262 | 0.5.9 / 2011-02-09
2263 | ==================
2264 | 
2265 |   * qs >= 0.0.4
2266 | 
2267 | 0.5.8 / 2011-02-04
2268 | ==================
2269 | 
2270 |   * Added `qs` dependency
2271 |   * Fixed router race-condition causing possible failure
2272 |     when `next()`ing to one or more routes with parallel
2273 |     requests
2274 | 
2275 | 0.5.7 / 2011-02-01
2276 | ==================
2277 | 
2278 |   * Added `onvhost()` call so Express (and others) can know when they are
2279 |   * Revert "Added stylus support" (use the middleware which ships with stylus)
2280 |   * Removed custom `Server#listen()` to allow regular `http.Server#listen()` args to work properly
2281 |   * Fixed long standing router issue (#83) that causes '.' to be disallowed within named placeholders in routes [Andreas Lind Petersen]
2282 |   * Fixed `utils.uid()` length error [Jxck]
2283 | mounted
2284 | 
2285 | 0.5.6 / 2011-01-23
2286 | ==================
2287 | 
2288 |   * Added stylus support to `compiler`
2289 |   * _favicon.js_ cleanup
2290 |   * _compiler.js_ cleanup
2291 |   * _bodyDecoder.js_ cleanup
2292 | 
2293 | 0.5.5 / 2011-01-13
2294 | ==================
2295 | 
2296 |   * Changed; using sha256 HMAC instead of md5. [Paul Querna]
2297 |   * Changed; generated a longer random UID, without time influence. [Paul Querna]
2298 |   * Fixed; session middleware throws when secret is not present. [Paul Querna]
2299 | 
2300 | 0.5.4 / 2011-01-07
2301 | ==================
2302 | 
2303 |   * Added; throw when router path or callback is missing
2304 |   * Fixed; `next(err)` on cookie parse exception instead of ignoring
2305 |   * Revert "Added utils.pathname(), memoized url.parse(str).pathname"
2306 | 
2307 | 0.5.3 / 2011-01-05
2308 | ==================
2309 | 
2310 |   * Added _docs/api.html_
2311 |   * Added `utils.pathname()`, memoized url.parse(str).pathname
2312 |   * Fixed `session.id` issue. Closes #183
2313 |   * Changed; Defaulting `staticProvider` maxAge to 0 not 1 year. Closes #179
2314 |   * Removed bad outdated docs, we need something new / automated eventually
2315 | 
2316 | 0.5.2 / 2010-12-28
2317 | ==================
2318 | 
2319 |   * Added default __OPTIONS__ support to _router_ middleware
2320 | 
2321 | 0.5.1 / 2010-12-28
2322 | ==================
2323 | 
2324 |   * Added `req.session.id` mirroring `req.sessionID`
2325 |   * Refactored router, exposing `connect.router.methods`
2326 |   * Exclude non-lib files from npm
2327 |   * Removed imposed headers `X-Powered-By`, `Server`, etc
2328 | 
2329 | 0.5.0 / 2010-12-06
2330 | ==================
2331 | 
2332 |   * Added _./index.js_
2333 |   * Added route segment precondition support and example
2334 |   * Added named capture group support to router
2335 | 
2336 | 0.4.0 / 2010-11-29
2337 | ==================
2338 | 
2339 |   * Added `basicAuth` middleware
2340 |   * Added more HTTP methods to the `router` middleware
2341 | 
2342 | 0.3.0 / 2010-07-21
2343 | ==================
2344 | 
2345 |   * Added _staticGzip_ middleware
2346 |   * Added `connect.utils` to expose utils
2347 |   * Added `connect.session.Session`
2348 |   * Added `connect.session.Store`
2349 |   * Added `connect.session.MemoryStore`
2350 |   * Added `connect.middleware` to expose the middleware getters
2351 |   * Added `buffer` option to _logger_ for performance increase
2352 |   * Added _favicon_ middleware for serving your own favicon or the connect default
2353 |   * Added option support to _staticProvider_, can now pass _root_ and _lifetime_.
2354 |   * Added; mounted `Server` instances now have the `route` property exposed for reflection
2355 |   * Added support for callback as first arg to `Server#use()`
2356 |   * Added support for `next(true)` in _router_ to bypass match attempts
2357 |   * Added `Server#listen()` _host_ support
2358 |   * Added `Server#route` when `Server#use()` is called with a route on a `Server` instance
2359 |   * Added _methodOverride_ X-HTTP-Method-Override support
2360 |   * Refactored session internals, adds _secret_ option
2361 |   * Renamed `lifetime` option to `maxAge` in _staticProvider_
2362 |   * Removed connect(1), it is now [spark(1)](http://github.com/senchalabs/spark)
2363 |   * Removed connect(1) dependency on examples, they can all now run with node(1)
2364 |   * Remove a typo that was leaking a global.
2365 |   * Removed `Object.prototype` forEach() and map() methods
2366 |   * Removed a few utils not used
2367 |   * Removed `connect.createApp()`
2368 |   * Removed `res.simpleBody()`
2369 |   * Removed _format_ middleware
2370 |   * Removed _flash_ middleware
2371 |   * Removed _redirect_ middleware
2372 |   * Removed _jsonrpc_ middleware, use [visionmedia/connect-jsonrpc](http://github.com/visionmedia/connect-jsonrpc)
2373 |   * Removed _pubsub_ middleware
2374 |   * Removed need for `params.{captures,splat}` in _router_ middleware, `params` is an array
2375 |   * Changed; _compiler_ no longer 404s
2376 |   * Changed; _router_ signature now matches connect middleware signature
2377 |   * Fixed a require in _session_ for default `MemoryStore`
2378 |   * Fixed nasty request body bug in _router_. Closes #54
2379 |   * Fixed _less_ support in _compiler_
2380 |   * Fixed bug preventing proper bubbling of exceptions in mounted servers
2381 |   * Fixed bug in `Server#use()` preventing `Server` instances as the first arg
2382 |   * Fixed **ENOENT** special case, is now treated as any other exception
2383 |   * Fixed spark env support
2384 | 
2385 | 0.2.1 / 2010-07-09
2386 | ==================
2387 | 
2388 |   * Added support for _router_ `next()` to continue calling matched routes
2389 |   * Added mime type for _cache.manifest_ files.
2390 |   * Changed _compiler_ middleware to use async require
2391 |   * Changed session api, stores now only require `#get()`, and `#set()`
2392 |   * Fixed _cacheManifest_ by adding `utils.find()` back
2393 | 
2394 | 0.2.0 / 2010-07-01
2395 | ==================
2396 | 
2397 |   * Added calls to `Session()` casts the given object as a `Session` instance
2398 |   * Added passing of `next()` to _router_ callbacks. Closes #46
2399 |   * Changed; `MemoryStore#destroy()` removes `req.session`
2400 |   * Changed `res.redirect("back")` to default to "/" when Referr?er is not present
2401 |   * Fixed _staticProvider_ urlencoded paths issue. Closes #47
2402 |   * Fixed _staticProvider_ middleware responding to **GET** requests
2403 |   * Fixed _jsonrpc_ middleware `Accept` header check. Closes #43
2404 |   * Fixed _logger_ format option
2405 |   * Fixed typo in _compiler_ middleware preventing the _dest_ option from working
2406 | 
2407 | 0.1.0 / 2010-06-25
2408 | ==================
2409 | 
2410 |   * Revamped the api, view the [Connect documentation](http://extjs.github.com/Connect/index.html#Middleware-Authoring) for more info (hover on the right for menu)
2411 |   * Added [extended api docs](http://extjs.github.com/Connect/api.html)
2412 |   * Added docs for several more middleware layers
2413 |   * Added `connect.Server#use()`
2414 |   * Added _compiler_ middleware which provides arbitrary static compilation
2415 |   * Added `req.originalUrl`
2416 |   * Removed _blog_ example
2417 |   * Removed _sass_ middleware (use _compiler_)
2418 |   * Removed _less_ middleware (use _compiler_)
2419 |   * Renamed middleware to be camelcase, _body-decoder_ is now _bodyDecoder_ etc.
2420 |   * Fixed `req.url` mutation bug when matching `connect.Server#use()` routes
2421 |   * Fixed `mkdir -p` implementation used in _bin/connect_. Closes #39
2422 |   * Fixed bug in _bodyDecoder_ throwing exceptions on request empty bodies
2423 |   * `make install` installing lib to $LIB_PREFIX aka $HOME/.node_libraries
2424 | 
2425 | 0.0.6 / 2010-06-22
2426 | ==================
2427 | 
2428 |   * Added _static_ middleware usage example
2429 |   * Added support for regular expressions as paths for _router_
2430 |   * Added `util.merge()`
2431 |   * Increased performance of _static_ by ~ 200 rps
2432 |   * Renamed the _rest_ middleware to _router_
2433 |   * Changed _rest_ api to accept a callback function
2434 |   * Removed _router_ middleware
2435 |   * Removed _proto.js_, only `Object#forEach()` remains
2436 | 
2437 | 0.0.5 / 2010-06-21
2438 | ==================
2439 | 
2440 |   * Added Server#use() which contains the Layer normalization logic
2441 |   * Added documentation for several middleware
2442 |   * Added several new examples
2443 |   * Added _less_ middleware
2444 |   * Added _repl_ middleware
2445 |   * Added _vhost_ middleware
2446 |   * Added _flash_ middleware
2447 |   * Added _cookie_ middleware
2448 |   * Added _session_ middleware
2449 |   * Added `utils.htmlEscape()`
2450 |   * Added `utils.base64Decode()`
2451 |   * Added `utils.base64Encode()`
2452 |   * Added `utils.uid()`
2453 |   * Added bin/connect app path and --config path support for .js suffix, although optional. Closes #26
2454 |   * Moved mime code to `utils.mime`, ex `utils.mime.types`, and `utils.mime.type()`
2455 |   * Renamed req.redirect() to res.redirect(). Closes #29
2456 |   * Fixed _sass_ 404 on **ENOENT**
2457 |   * Fixed +new Date duplication. Closes #24
2458 | 
2459 | 0.0.4 / 2010-06-16
2460 | ==================
2461 | 
2462 |   * Added workerPidfile() to bin/connect
2463 |   * Added --workers support to bin/connect stop and status commands
2464 |   * Added _redirect_ middleware
2465 |   * Added better --config support to bin/connect. All flags can be utilized
2466 |   * Added auto-detection of _./config.js_
2467 |   * Added config example
2468 |   * Added `net.Server` support to bin/connect
2469 |   * Writing worker pids relative to `env.pidfile`
2470 |   * s/parseQuery/parse/g
2471 |   * Fixed npm support
2472 | 
2473 | 0.0.3 / 2010-06-16
2474 | ==================
2475 | 
2476 |   * Fixed node dependency in package.json, now _">= 0.1.98-0"_ to support __HEAD__
2477 | 
2478 | 0.0.2 / 2010-06-15
2479 | ==================
2480 | 
2481 |   * Added `-V, --version` to bin/connect
2482 |   * Added `utils.parseCookie()`
2483 |   * Added `utils.serializeCookie()`
2484 |   * Added `utils.toBoolean()`
2485 |   * Added _sass_ middleware
2486 |   * Added _cookie_ middleware
2487 |   * Added _format_ middleware
2488 |   * Added _lint_ middleware
2489 |   * Added _rest_ middleware
2490 |   * Added _./package.json_ (npm install connect)
2491 |   * Added `handleError()` support
2492 |   * Added `process.connectEnv`
2493 |   * Added custom log format support to _log_ middleware
2494 |   * Added arbitrary env variable support to bin/connect (ext: --logFormat ":method :url")
2495 |   * Added -w, --workers to bin/connect
2496 |   * Added bin/connect support for --user NAME and --group NAME
2497 |   * Fixed url re-writing support
2498 | 
2499 | 0.0.1 / 2010-06-03
2500 | ==================
2501 | 
2502 |   * Initial release
2503 | 
2504 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | (The MIT License)
 2 | 
 3 | Copyright (c) 2010 Sencha Inc.
 4 | Copyright (c) 2011 LearnBoost
 5 | Copyright (c) 2011-2014 TJ Holowaychuk
 6 | Copyright (c) 2015 Douglas Christopher Wilson
 7 | 
 8 | Permission is hereby granted, free of charge, to any person obtaining
 9 | a copy of this software and associated documentation files (the
10 | 'Software'), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 | 
16 | The above copyright notice and this permission notice shall be
17 | included in all copies or substantial portions of the Software.
18 | 
19 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | <div align="center">
  2 | 
  3 | <img src="logo/horizontal.png" alt="connect logo" width="450px">
  4 | 
  5 | [![NPM Version][npm-version-image]][npm-url]
  6 | [![NPM Downloads][npm-downloads-image]][npm-url]
  7 | [![Build Status][github-actions-ci-image]][github-actions-ci-url]
  8 | [![Test Coverage][coveralls-image]][coveralls-url]
  9 | 
 10 | </div>
 11 | 
 12 |   Connect is an extensible HTTP server framework for [node](http://nodejs.org) using "plugins" known as _middleware_.
 13 | 
 14 | ```js
 15 | var connect = require('connect');
 16 | var http = require('http');
 17 | 
 18 | var app = connect();
 19 | 
 20 | // gzip/deflate outgoing responses
 21 | var compression = require('compression');
 22 | app.use(compression());
 23 | 
 24 | // store session state in browser cookie
 25 | var cookieSession = require('cookie-session');
 26 | app.use(cookieSession({
 27 |     keys: ['secret1', 'secret2']
 28 | }));
 29 | 
 30 | // parse urlencoded request bodies into req.body
 31 | var bodyParser = require('body-parser');
 32 | app.use(bodyParser.urlencoded({extended: false}));
 33 | 
 34 | // respond to all requests
 35 | app.use(function(req, res){
 36 |   res.end('Hello from Connect!\n');
 37 | });
 38 | 
 39 | //create node.js http server and listen on port
 40 | http.createServer(app).listen(3000);
 41 | ```
 42 | 
 43 | ## Getting Started
 44 | 
 45 | Connect is a simple framework to glue together various "middleware" to handle requests.
 46 | 
 47 | ### Install Connect
 48 | 
 49 | ```sh
 50 | $ npm install connect
 51 | ```
 52 | 
 53 | ### Create an app
 54 | 
 55 | The main component is a Connect "app". This will store all the middleware
 56 | added and is, itself, a function.
 57 | 
 58 | ```js
 59 | var app = connect();
 60 | ```
 61 | 
 62 | ### Use middleware
 63 | 
 64 | The core of Connect is "using" middleware. Middleware are added as a "stack"
 65 | where incoming requests will execute each middleware one-by-one until a middleware
 66 | does not call `next()` within it.
 67 | 
 68 | ```js
 69 | app.use(function middleware1(req, res, next) {
 70 |   // middleware 1
 71 |   next();
 72 | });
 73 | app.use(function middleware2(req, res, next) {
 74 |   // middleware 2
 75 |   next();
 76 | });
 77 | ```
 78 | 
 79 | ### Mount middleware
 80 | 
 81 | The `.use()` method also takes an optional path string that is matched against
 82 | the beginning of the incoming request URL. This allows for basic routing.
 83 | 
 84 | ```js
 85 | app.use('/foo', function fooMiddleware(req, res, next) {
 86 |   // req.url starts with "/foo"
 87 |   next();
 88 | });
 89 | app.use('/bar', function barMiddleware(req, res, next) {
 90 |   // req.url starts with "/bar"
 91 |   next();
 92 | });
 93 | ```
 94 | 
 95 | ### Error middleware
 96 | 
 97 | There are special cases of "error-handling" middleware. There are middleware
 98 | where the function takes exactly 4 arguments. When a middleware passes an error
 99 | to `next`, the app will proceed to look for the error middleware that was declared
100 | after that middleware and invoke it, skipping any error middleware above that
101 | middleware and any non-error middleware below.
102 | 
103 | ```js
104 | // regular middleware
105 | app.use(function (req, res, next) {
106 |   // i had an error
107 |   next(new Error('boom!'));
108 | });
109 | 
110 | // error middleware for errors that occurred in middleware
111 | // declared before this
112 | app.use(function onerror(err, req, res, next) {
113 |   // an error occurred!
114 | });
115 | ```
116 | 
117 | ### Create a server from the app
118 | 
119 | The last step is to actually use the Connect app in a server. The `.listen()` method
120 | is a convenience to start a HTTP server (and is identical to the `http.Server`'s `listen`
121 | method in the version of Node.js you are running).
122 | 
123 | ```js
124 | var server = app.listen(port);
125 | ```
126 | 
127 | The app itself is really just a function with three arguments, so it can also be handed
128 | to `.createServer()` in Node.js.
129 | 
130 | ```js
131 | var server = http.createServer(app);
132 | ```
133 | 
134 | ## Middleware
135 | 
136 | These middleware and libraries are officially supported by the Connect/Express team:
137 | 
138 |   - [body-parser](https://www.npmjs.com/package/body-parser) - previous `bodyParser`, `json`, and `urlencoded`. You may also be interested in:
139 |     - [body](https://www.npmjs.com/package/body)
140 |     - [co-body](https://www.npmjs.com/package/co-body)
141 |     - [raw-body](https://www.npmjs.com/package/raw-body)
142 |   - [compression](https://www.npmjs.com/package/compression) - previously `compress`
143 |   - [connect-timeout](https://www.npmjs.com/package/connect-timeout) - previously `timeout`
144 |   - [cookie-parser](https://www.npmjs.com/package/cookie-parser) - previously `cookieParser`
145 |   - [cookie-session](https://www.npmjs.com/package/cookie-session) - previously `cookieSession`
146 |   - [csurf](https://www.npmjs.com/package/csurf) - previously `csrf`
147 |   - [errorhandler](https://www.npmjs.com/package/errorhandler) - previously `error-handler`
148 |   - [express-session](https://www.npmjs.com/package/express-session) - previously `session`
149 |   - [method-override](https://www.npmjs.com/package/method-override) - previously `method-override`
150 |   - [morgan](https://www.npmjs.com/package/morgan) - previously `logger`
151 |   - [response-time](https://www.npmjs.com/package/response-time) - previously `response-time`
152 |   - [serve-favicon](https://www.npmjs.com/package/serve-favicon) - previously `favicon`
153 |   - [serve-index](https://www.npmjs.com/package/serve-index) - previously `directory`
154 |   - [serve-static](https://www.npmjs.com/package/serve-static) - previously `static`
155 |   - [vhost](https://www.npmjs.com/package/vhost) - previously `vhost`
156 | 
157 | Most of these are exact ports of their Connect 2.x equivalents. The primary exception is `cookie-session`.
158 | 
159 | Some middleware previously included with Connect are no longer supported by the Connect/Express team, are replaced by an alternative module, or should be superseded by a better module. Use one of these alternatives instead:
160 | 
161 |   - `cookieParser`
162 |     - [cookies](https://www.npmjs.com/package/cookies) and [keygrip](https://www.npmjs.com/package/keygrip)
163 |   - `limit`
164 |     - [raw-body](https://www.npmjs.com/package/raw-body)
165 |   - `multipart`
166 |     - [connect-multiparty](https://www.npmjs.com/package/connect-multiparty)
167 |     - [connect-busboy](https://www.npmjs.com/package/connect-busboy)
168 |   - `query`
169 |     - [qs](https://www.npmjs.com/package/qs)
170 |   - `staticCache`
171 |     - [st](https://www.npmjs.com/package/st)
172 |     - [connect-static](https://www.npmjs.com/package/connect-static)
173 | 
174 | Checkout [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) for many other compatible middleware!
175 | 
176 | ## API
177 | 
178 | The Connect API is very minimalist, enough to create an app and add a chain
179 | of middleware.
180 | 
181 | When the `connect` module is required, a function is returned that will construct
182 | a new app when called.
183 | 
184 | ```js
185 | // require module
186 | var connect = require('connect')
187 | 
188 | // create app
189 | var app = connect()
190 | ```
191 | 
192 | ### app(req, res[, next])
193 | 
194 | The `app` itself is a function. This is just an alias to `app.handle`.
195 | 
196 | ### app.handle(req, res[, out])
197 | 
198 | Calling the function will run the middleware stack against the given Node.js
199 | http request (`req`) and response (`res`) objects. An optional function `out`
200 | can be provided that will be called if the request (or error) was not handled
201 | by the middleware stack.
202 | 
203 | ### app.listen([...])
204 | 
205 | Start the app listening for requests. This method will internally create a Node.js
206 | HTTP server and call `.listen()` on it.
207 | 
208 | This is an alias to the `server.listen()` method in the version of Node.js running,
209 | so consult the Node.js documentation for all the different variations. The most
210 | common signature is [`app.listen(port)`](https://nodejs.org/dist/latest-v6.x/docs/api/http.html#http_server_listen_port_hostname_backlog_callback).
211 | 
212 | ### app.use(fn)
213 | 
214 | Use a function on the app, where the function represents a middleware. The function
215 | will be invoked for every request in the order that `app.use` is called. The function
216 | is called with three arguments:
217 | 
218 | ```js
219 | app.use(function (req, res, next) {
220 |   // req is the Node.js http request object
221 |   // res is the Node.js http response object
222 |   // next is a function to call to invoke the next middleware
223 | })
224 | ```
225 | 
226 | In addition to a plan function, the `fn` argument can also be a Node.js HTTP server
227 | instance or another Connect app instance.
228 | 
229 | ### app.use(route, fn)
230 | 
231 | Use a function on the app, where the function represents a middleware. The function
232 | will be invoked for every request in which the URL (`req.url` property) starts with
233 | the given `route` string in the order that `app.use` is called. The function is
234 | called with three arguments:
235 | 
236 | ```js
237 | app.use('/foo', function (req, res, next) {
238 |   // req is the Node.js http request object
239 |   // res is the Node.js http response object
240 |   // next is a function to call to invoke the next middleware
241 | })
242 | ```
243 | 
244 | In addition to a plan function, the `fn` argument can also be a Node.js HTTP server
245 | instance or another Connect app instance.
246 | 
247 | The `route` is always terminated at a path separator (`/`) or a dot (`.`) character.
248 | This means the given routes `/foo/` and `/foo` are the same and both will match requests
249 | with the URLs `/foo`, `/foo/`, `/foo/bar`, and `/foo.bar`, but not match a request with
250 | the URL `/foobar`.
251 | 
252 | The `route` is matched in a case-insensitive manner.
253 | 
254 | In order to make middleware easier to write to be agnostic of the `route`, when the
255 | `fn` is invoked, the `req.url` will be altered to remove the `route` part (and the
256 | original will be available as `req.originalUrl`). For example, if `fn` is used at the
257 | route `/foo`, the request for `/foo/bar` will invoke `fn` with `req.url === '/bar'`
258 | and `req.originalUrl === '/foo/bar'`.
259 | 
260 | ## Running Tests
261 | 
262 | ```bash
263 | npm install
264 | npm test
265 | ```
266 | 
267 | ## People
268 | 
269 | The Connect project would not be the same without all the people involved.
270 | 
271 | The original author of Connect is [TJ Holowaychuk](https://github.com/tj)
272 | 
273 | The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson)
274 | 
275 | [List of all contributors](https://github.com/senchalabs/connect/graphs/contributors)
276 | 
277 | ## License
278 | 
279 | [MIT](LICENSE)
280 | 
281 | [coveralls-image]: https://badgen.net/coveralls/c/github/senchalabs/connect/master
282 | [coveralls-url]: https://coveralls.io/r/senchalabs/connect?branch=master
283 | [github-actions-ci-image]: https://badgen.net/github/checks/senchalabs/connect/master?label=ci
284 | [github-actions-ci-url]: https://github.com/jshttp/senchalabs/connect?query=workflow%3Aci
285 | [npm-downloads-image]: https://badgen.net/npm/dm/connect
286 | [npm-url]: https://npmjs.org/package/connect
287 | [npm-version-image]: https://badgen.net/npm/v/connect
288 | 


--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
 1 | # Security Policies and Procedures
 2 | 
 3 | This document outlines security procedures and general policies for the Connect
 4 | project.
 5 | 
 6 |   * [Reporting a Bug](#reporting-a-bug)
 7 |   * [Disclosure Policy](#disclosure-policy)
 8 |   * [Comments on this Policy](#comments-on-this-policy)
 9 | 
10 | ## Reporting a Bug
11 | 
12 | The Connect team and community take all security bugs in Connect seriously.
13 | Thank you for improving the security of Connect. We appreciate your efforts and
14 | responsible disclosure and will make every effort to acknowledge your
15 | contributions.
16 | 
17 | Report security bugs by emailing the lead maintainer in the README.md file.
18 | 
19 | The lead maintainer will acknowledge your email within 48 hours, and will send a
20 | more detailed response within 48 hours indicating the next steps in handling
21 | your report. After the initial reply to your report, the security team will
22 | endeavor to keep you informed of the progress towards a fix and full
23 | announcement, and may ask for additional information or guidance.
24 | 
25 | Report security bugs in third-party modules to the person or team maintaining
26 | the module. You can also report a vulnerability through the
27 | [Node Security Project](https://nodesecurity.io/report).
28 | 
29 | ## Disclosure Policy
30 | 
31 | When the security team receives a security bug report, they will assign it to a
32 | primary handler. This person will coordinate the fix and release process,
33 | involving the following steps:
34 | 
35 |   * Confirm the problem and determine the affected versions.
36 |   * Audit code to find any potential similar problems.
37 |   * Prepare fixes for all releases still under maintenance. These fixes will be
38 |     released as fast as possible to npm.
39 | 
40 | ## Comments on this Policy
41 | 
42 | If you have suggestions on how this process could be improved please submit a
43 | pull request.
44 | 


--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
  1 | /*!
  2 |  * connect
  3 |  * Copyright(c) 2010 Sencha Inc.
  4 |  * Copyright(c) 2011 TJ Holowaychuk
  5 |  * Copyright(c) 2015 Douglas Christopher Wilson
  6 |  * MIT Licensed
  7 |  */
  8 | 
  9 | 'use strict';
 10 | 
 11 | /**
 12 |  * Module dependencies.
 13 |  * @private
 14 |  */
 15 | 
 16 | var debug = require('debug')('connect:dispatcher');
 17 | var EventEmitter = require('events').EventEmitter;
 18 | var finalhandler = require('finalhandler');
 19 | var http = require('http');
 20 | var merge = require('utils-merge');
 21 | var parseUrl = require('parseurl');
 22 | 
 23 | /**
 24 |  * Module exports.
 25 |  * @public
 26 |  */
 27 | 
 28 | module.exports = createServer;
 29 | 
 30 | /**
 31 |  * Module variables.
 32 |  * @private
 33 |  */
 34 | 
 35 | var env = process.env.NODE_ENV || 'development';
 36 | var proto = {};
 37 | 
 38 | /* istanbul ignore next */
 39 | var defer = typeof setImmediate === 'function'
 40 |   ? setImmediate
 41 |   : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
 42 | 
 43 | /**
 44 |  * Create a new connect server.
 45 |  *
 46 |  * @return {function}
 47 |  * @public
 48 |  */
 49 | 
 50 | function createServer() {
 51 |   function app(req, res, next){ app.handle(req, res, next); }
 52 |   merge(app, proto);
 53 |   merge(app, EventEmitter.prototype);
 54 |   app.route = '/';
 55 |   app.stack = [];
 56 |   return app;
 57 | }
 58 | 
 59 | /**
 60 |  * Utilize the given middleware `handle` to the given `route`,
 61 |  * defaulting to _/_. This "route" is the mount-point for the
 62 |  * middleware, when given a value other than _/_ the middleware
 63 |  * is only effective when that segment is present in the request's
 64 |  * pathname.
 65 |  *
 66 |  * For example if we were to mount a function at _/admin_, it would
 67 |  * be invoked on _/admin_, and _/admin/settings_, however it would
 68 |  * not be invoked for _/_, or _/posts_.
 69 |  *
 70 |  * @param {String|Function|Server} route, callback or server
 71 |  * @param {Function|Server} callback or server
 72 |  * @return {Server} for chaining
 73 |  * @public
 74 |  */
 75 | 
 76 | proto.use = function use(route, fn) {
 77 |   var handle = fn;
 78 |   var path = route;
 79 | 
 80 |   // default route to '/'
 81 |   if (typeof route !== 'string') {
 82 |     handle = route;
 83 |     path = '/';
 84 |   }
 85 | 
 86 |   // wrap sub-apps
 87 |   if (typeof handle.handle === 'function') {
 88 |     var server = handle;
 89 |     server.route = path;
 90 |     handle = function (req, res, next) {
 91 |       server.handle(req, res, next);
 92 |     };
 93 |   }
 94 | 
 95 |   // wrap vanilla http.Servers
 96 |   if (handle instanceof http.Server) {
 97 |     handle = handle.listeners('request')[0];
 98 |   }
 99 | 
100 |   // strip trailing slash
101 |   if (path[path.length - 1] === '/') {
102 |     path = path.slice(0, -1);
103 |   }
104 | 
105 |   // add the middleware
106 |   debug('use %s %s', path || '/', handle.name || 'anonymous');
107 |   this.stack.push({ route: path, handle: handle });
108 | 
109 |   return this;
110 | };
111 | 
112 | /**
113 |  * Handle server requests, punting them down
114 |  * the middleware stack.
115 |  *
116 |  * @private
117 |  */
118 | 
119 | proto.handle = function handle(req, res, out) {
120 |   var index = 0;
121 |   var protohost = getProtohost(req.url) || '';
122 |   var removed = '';
123 |   var slashAdded = false;
124 |   var stack = this.stack;
125 | 
126 |   // final function handler
127 |   var done = out || finalhandler(req, res, {
128 |     env: env,
129 |     onerror: logerror
130 |   });
131 | 
132 |   // store the original URL
133 |   req.originalUrl = req.originalUrl || req.url;
134 | 
135 |   function next(err) {
136 |     if (slashAdded) {
137 |       req.url = req.url.substr(1);
138 |       slashAdded = false;
139 |     }
140 | 
141 |     if (removed.length !== 0) {
142 |       req.url = protohost + removed + req.url.substr(protohost.length);
143 |       removed = '';
144 |     }
145 | 
146 |     // next callback
147 |     var layer = stack[index++];
148 | 
149 |     // all done
150 |     if (!layer) {
151 |       defer(done, err);
152 |       return;
153 |     }
154 | 
155 |     // route data
156 |     var path = parseUrl(req).pathname || '/';
157 |     var route = layer.route;
158 | 
159 |     // skip this layer if the route doesn't match
160 |     if (path.toLowerCase().substr(0, route.length) !== route.toLowerCase()) {
161 |       return next(err);
162 |     }
163 | 
164 |     // skip if route match does not border "/", ".", or end
165 |     var c = path.length > route.length && path[route.length];
166 |     if (c && c !== '/' && c !== '.') {
167 |       return next(err);
168 |     }
169 | 
170 |     // trim off the part of the url that matches the route
171 |     if (route.length !== 0 && route !== '/') {
172 |       removed = route;
173 |       req.url = protohost + req.url.substr(protohost.length + removed.length);
174 | 
175 |       // ensure leading slash
176 |       if (!protohost && req.url[0] !== '/') {
177 |         req.url = '/' + req.url;
178 |         slashAdded = true;
179 |       }
180 |     }
181 | 
182 |     // call the layer handle
183 |     call(layer.handle, route, err, req, res, next);
184 |   }
185 | 
186 |   next();
187 | };
188 | 
189 | /**
190 |  * Listen for connections.
191 |  *
192 |  * This method takes the same arguments
193 |  * as node's `http.Server#listen()`.
194 |  *
195 |  * HTTP and HTTPS:
196 |  *
197 |  * If you run your application both as HTTP
198 |  * and HTTPS you may wrap them individually,
199 |  * since your Connect "server" is really just
200 |  * a JavaScript `Function`.
201 |  *
202 |  *      var connect = require('connect')
203 |  *        , http = require('http')
204 |  *        , https = require('https');
205 |  *
206 |  *      var app = connect();
207 |  *
208 |  *      http.createServer(app).listen(80);
209 |  *      https.createServer(options, app).listen(443);
210 |  *
211 |  * @return {http.Server}
212 |  * @api public
213 |  */
214 | 
215 | proto.listen = function listen() {
216 |   var server = http.createServer(this);
217 |   return server.listen.apply(server, arguments);
218 | };
219 | 
220 | /**
221 |  * Invoke a route handle.
222 |  * @private
223 |  */
224 | 
225 | function call(handle, route, err, req, res, next) {
226 |   var arity = handle.length;
227 |   var error = err;
228 |   var hasError = Boolean(err);
229 | 
230 |   debug('%s %s : %s', handle.name || '<anonymous>', route, req.originalUrl);
231 | 
232 |   try {
233 |     if (hasError && arity === 4) {
234 |       // error-handling middleware
235 |       handle(err, req, res, next);
236 |       return;
237 |     } else if (!hasError && arity < 4) {
238 |       // request-handling middleware
239 |       handle(req, res, next);
240 |       return;
241 |     }
242 |   } catch (e) {
243 |     // replace the error
244 |     error = e;
245 |   }
246 | 
247 |   // continue
248 |   next(error);
249 | }
250 | 
251 | /**
252 |  * Log error using console.error.
253 |  *
254 |  * @param {Error} err
255 |  * @private
256 |  */
257 | 
258 | function logerror(err) {
259 |   if (env !== 'test') console.error(err.stack || err.toString());
260 | }
261 | 
262 | /**
263 |  * Get get protocol + host for a URL.
264 |  *
265 |  * @param {string} url
266 |  * @private
267 |  */
268 | 
269 | function getProtohost(url) {
270 |   if (url.length === 0 || url[0] === '/') {
271 |     return undefined;
272 |   }
273 | 
274 |   var fqdnIndex = url.indexOf('://')
275 | 
276 |   return fqdnIndex !== -1 && url.lastIndexOf('?', fqdnIndex) === -1
277 |     ? url.substr(0, url.indexOf('/', 3 + fqdnIndex))
278 |     : undefined;
279 | }
280 | 


--------------------------------------------------------------------------------
/logo/horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/senchalabs/connect/98ab0c435852b311ed57fe48a1846c2dae84e266/logo/horizontal.png


--------------------------------------------------------------------------------
/logo/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/senchalabs/connect/98ab0c435852b311ed57fe48a1846c2dae84e266/logo/icon.png


--------------------------------------------------------------------------------
/logo/vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/senchalabs/connect/98ab0c435852b311ed57fe48a1846c2dae84e266/logo/vertical.png


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "connect",
 3 |   "description": "High performance middleware framework",
 4 |   "version": "3.7.0",
 5 |   "author": "TJ Holowaychuk <tj@vision-media.ca> (http://tjholowaychuk.com)",
 6 |   "contributors": [
 7 |     "Douglas Christopher Wilson <doug@somethingdoug.com>",
 8 |     "Jonathan Ong <me@jongleberry.com>",
 9 |     "Tim Caswell <tim@creationix.com>"
10 |   ],
11 |   "keywords": [
12 |     "framework",
13 |     "web",
14 |     "middleware",
15 |     "connect",
16 |     "rack"
17 |   ],
18 |   "repository": "senchalabs/connect",
19 |   "dependencies": {
20 |     "debug": "2.6.9",
21 |     "finalhandler": "1.1.2",
22 |     "parseurl": "~1.3.3",
23 |     "utils-merge": "1.0.1"
24 |   },
25 |   "devDependencies": {
26 |     "eslint": "8.57.0",
27 |     "mocha": "10.7.3",
28 |     "nyc": "17.1.0",
29 |     "supertest": "6.3.4"
30 |   },
31 |   "license": "MIT",
32 |   "files": [
33 |     "LICENSE",
34 |     "HISTORY.md",
35 |     "README.md",
36 |     "SECURITY.md",
37 |     "index.js"
38 |   ],
39 |   "engines": {
40 |     "node": ">= 0.10.0"
41 |   },
42 |   "scripts": {
43 |     "lint": "eslint .",
44 |     "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/",
45 |     "test-ci": "nyc --reporter=lcov --reporter=text npm test",
46 |     "test-cov": "nyc --reporter=html --reporter=text npm test"
47 |   }
48 | }
49 | 


--------------------------------------------------------------------------------
/test/app.listen.js:
--------------------------------------------------------------------------------
 1 | 
 2 | var assert = require('assert')
 3 | var connect = require('..');
 4 | var request = require('supertest');
 5 | 
 6 | describe('app.listen()', function(){
 7 |   it('should wrap in an http.Server', function(done){
 8 |     var app = connect();
 9 | 
10 |     app.use(function(req, res){
11 |       res.end();
12 |     });
13 | 
14 |     var server = app.listen(0, function () {
15 |       assert.ok(server)
16 |       request(server)
17 |         .get('/')
18 |         .expect(200, function (err) {
19 |           server.close(function () {
20 |             done(err)
21 |           })
22 |         })
23 |     });
24 |   });
25 | });
26 | 


--------------------------------------------------------------------------------
/test/fqdn.js:
--------------------------------------------------------------------------------
 1 | 
 2 | var connect = require('..');
 3 | var rawrequest = require('./support/rawagent')
 4 | 
 5 | describe('app.use()', function(){
 6 |   var app;
 7 | 
 8 |   beforeEach(function(){
 9 |     app = connect();
10 |   });
11 | 
12 |   it('should not obscure FQDNs', function(done){
13 |     app.use(function(req, res){
14 |       res.end(req.url);
15 |     });
16 | 
17 |     rawrequest(app)
18 |       .get('http://example.com/foo')
19 |       .expect(200, 'http://example.com/foo', done)
20 |   });
21 | 
22 |   describe('with a connect app', function(){
23 |     it('should ignore FQDN in search', function (done) {
24 |       app.use('/proxy', function (req, res) {
25 |         res.end(req.url);
26 |       });
27 | 
28 |       rawrequest(app)
29 |         .get('/proxy?url=http://example.com/blog/post/1')
30 |         .expect(200, '/?url=http://example.com/blog/post/1', done)
31 |     });
32 | 
33 |     it('should ignore FQDN in path', function (done) {
34 |       app.use('/proxy', function (req, res) {
35 |         res.end(req.url);
36 |       });
37 | 
38 |       rawrequest(app)
39 |         .get('/proxy/http://example.com/blog/post/1')
40 |         .expect(200, '/http://example.com/blog/post/1', done)
41 |     });
42 | 
43 |     it('should adjust FQDN req.url', function(done){
44 |       app.use('/blog', function(req, res){
45 |         res.end(req.url);
46 |       });
47 | 
48 |       rawrequest(app)
49 |         .get('http://example.com/blog/post/1')
50 |         .expect(200, 'http://example.com/post/1', done)
51 |     });
52 | 
53 |     it('should adjust FQDN req.url with multiple handlers', function(done){
54 |       app.use(function(req,res,next) {
55 |         next();
56 |       });
57 | 
58 |       app.use('/blog', function(req, res){
59 |         res.end(req.url);
60 |       });
61 | 
62 |       rawrequest(app)
63 |         .get('http://example.com/blog/post/1')
64 |         .expect(200, 'http://example.com/post/1', done)
65 |     });
66 | 
67 |     it('should adjust FQDN req.url with multiple routed handlers', function(done) {
68 |       app.use('/blog', function(req,res,next) {
69 |         next();
70 |       });
71 |       app.use('/blog', function(req, res) {
72 |         res.end(req.url);
73 |       });
74 | 
75 |       rawrequest(app)
76 |         .get('http://example.com/blog/post/1')
77 |         .expect(200, 'http://example.com/post/1', done)
78 |     });
79 |   });
80 | });
81 | 


--------------------------------------------------------------------------------
/test/mounting.js:
--------------------------------------------------------------------------------
  1 | 
  2 | var assert = require('assert');
  3 | var connect = require('..');
  4 | var http = require('http');
  5 | var request = require('supertest');
  6 | 
  7 | describe('app.use()', function(){
  8 |   var app;
  9 | 
 10 |   beforeEach(function(){
 11 |     app = connect();
 12 |   });
 13 | 
 14 |   it('should match all paths with "/"', function (done) {
 15 |     app.use('/', function (req, res) {
 16 |       res.end(req.url);
 17 |     });
 18 | 
 19 |     request(app)
 20 |       .get('/blog')
 21 |       .expect(200, '/blog', done)
 22 |   });
 23 | 
 24 |   it('should match full path', function (done) {
 25 |     app.use('/blog', function (req, res) {
 26 |       res.end(req.url);
 27 |     });
 28 | 
 29 |     request(app)
 30 |       .get('/blog')
 31 |       .expect(200, '/', done)
 32 |   });
 33 | 
 34 |   it('should match left-side of path', function (done) {
 35 |     app.use('/blog', function (req, res) {
 36 |       res.end(req.url);
 37 |     });
 38 | 
 39 |     request(app)
 40 |       .get('/blog/article/1')
 41 |       .expect(200, '/article/1', done)
 42 |   });
 43 | 
 44 |   it('should match up to dot', function (done) {
 45 |     app.use('/blog', function (req, res) {
 46 |       res.end(req.url)
 47 |     })
 48 | 
 49 |     request(app)
 50 |       .get('/blog.json')
 51 |       .expect(200, done)
 52 |   })
 53 | 
 54 |   it('should not match shorter path', function (done) {
 55 |     app.use('/blog-o-rama', function (req, res) {
 56 |       res.end(req.url);
 57 |     });
 58 | 
 59 |     request(app)
 60 |       .get('/blog')
 61 |       .expect(404, done)
 62 |   });
 63 | 
 64 |   it('should not end match in middle of component', function (done) {
 65 |     app.use('/blog', function (req, res) {
 66 |       res.end(req.url);
 67 |     });
 68 | 
 69 |     request(app)
 70 |       .get('/blog-o-rama/article/1')
 71 |       .expect(404, done)
 72 |   });
 73 | 
 74 |   it('should be case insensitive (lower-case route, mixed-case request)', function(done){
 75 |     var blog = http.createServer(function(req, res){
 76 |       assert.equal(req.url, '/');
 77 |       res.end('blog');
 78 |     });
 79 | 
 80 |     app.use('/blog', blog);
 81 | 
 82 |     request(app)
 83 |       .get('/BLog')
 84 |       .expect('blog', done)
 85 |   });
 86 | 
 87 |   it('should be case insensitive (mixed-case route, lower-case request)', function(done){
 88 |     var blog = http.createServer(function(req, res){
 89 |       assert.equal(req.url, '/');
 90 |       res.end('blog');
 91 |     });
 92 | 
 93 |     app.use('/BLog', blog);
 94 | 
 95 |     request(app)
 96 |       .get('/blog')
 97 |       .expect('blog', done)
 98 |   });
 99 | 
100 |   it('should be case insensitive (mixed-case route, mixed-case request)', function(done){
101 |     var blog = http.createServer(function(req, res){
102 |       assert.equal(req.url, '/');
103 |       res.end('blog');
104 |     });
105 | 
106 |     app.use('/BLog', blog);
107 | 
108 |     request(app)
109 |       .get('/blOG')
110 |       .expect('blog', done)
111 |   });
112 | 
113 |   it('should ignore fn.arity > 4', function(done){
114 |     var invoked = [];
115 | 
116 |     app.use(function(req, res, next, _a, _b){
117 |       invoked.push(0)
118 |       next();
119 |     });
120 |     app.use(function(req, res, next){
121 |       invoked.push(1)
122 |       next(new Error('err'));
123 |     });
124 |     app.use(function(err, req, res, next){
125 |       invoked.push(2);
126 |       res.end(invoked.join(','));
127 |     });
128 | 
129 |     request(app)
130 |       .get('/')
131 |       .expect(200, '1,2', done)
132 |   });
133 | 
134 |   describe('with a connect app', function(){
135 |     it('should mount', function(done){
136 |       var blog = connect();
137 | 
138 |       blog.use(function(req, res){
139 |         assert.equal(req.url, '/');
140 |         res.end('blog');
141 |       });
142 | 
143 |       app.use('/blog', blog);
144 | 
145 |       request(app)
146 |         .get('/blog')
147 |         .expect(200, 'blog', done)
148 |     });
149 | 
150 |     it('should retain req.originalUrl', function(done){
151 |       var app = connect();
152 | 
153 |       app.use('/blog', function(req, res){
154 |         res.end(req.originalUrl);
155 |       });
156 | 
157 |       request(app)
158 |         .get('/blog/post/1')
159 |         .expect(200, '/blog/post/1', done)
160 |     });
161 | 
162 |     it('should adjust req.url', function(done){
163 |       app.use('/blog', function(req, res){
164 |         res.end(req.url);
165 |       });
166 | 
167 |       request(app)
168 |         .get('/blog/post/1')
169 |         .expect(200, '/post/1', done)
170 |     });
171 | 
172 |     it('should strip trailing slash', function(done){
173 |       var blog = connect();
174 | 
175 |       blog.use(function(req, res){
176 |         assert.equal(req.url, '/');
177 |         res.end('blog');
178 |       });
179 | 
180 |       app.use('/blog/', blog);
181 | 
182 |       request(app)
183 |         .get('/blog')
184 |         .expect('blog', done)
185 |     });
186 | 
187 |     it('should set .route', function(){
188 |       var blog = connect();
189 |       var admin = connect();
190 |       app.use('/blog', blog);
191 |       blog.use('/admin', admin);
192 |       assert.equal(app.route, '/');
193 |       assert.equal(blog.route, '/blog');
194 |       assert.equal(admin.route, '/admin');
195 |     });
196 | 
197 |     it('should not add trailing slash to req.url', function(done) {
198 |       app.use('/admin', function(req, res, next) {
199 |         next();
200 |       });
201 | 
202 |       app.use(function(req, res, next) {
203 |         res.end(req.url);
204 |       });
205 | 
206 |       request(app)
207 |         .get('/admin')
208 |         .expect('/admin', done)
209 |     })
210 |   })
211 | 
212 |   describe('with a node app', function(){
213 |     it('should mount', function(done){
214 |       var blog = http.createServer(function(req, res){
215 |         assert.equal(req.url, '/');
216 |         res.end('blog');
217 |       });
218 | 
219 |       app.use('/blog', blog);
220 | 
221 |       request(app)
222 |         .get('/blog')
223 |         .expect('blog', done)
224 |     });
225 |   });
226 | 
227 |   describe('error handling', function(){
228 |     it('should send errors to airty 4 fns', function(done){
229 |       app.use(function(req, res, next){
230 |         next(new Error('msg'));
231 |       })
232 |       app.use(function(err, req, res, next){
233 |         res.end('got error ' + err.message);
234 |       });
235 | 
236 |       request(app)
237 |         .get('/')
238 |         .expect('got error msg', done)
239 |     })
240 | 
241 |     it('should skip to non-error middleware', function(done){
242 |       var invoked = false;
243 | 
244 |       app.use(function(req, res, next){
245 |         next(new Error('msg'));
246 |       })
247 |       app.use(function(req, res, next){
248 |         invoked = true;
249 |         next();
250 |       });
251 |       app.use(function(err, req, res, next){
252 |         res.end(invoked ? 'invoked' : err.message);
253 |       });
254 | 
255 |       request(app)
256 |         .get('/')
257 |         .expect(200, 'msg', done)
258 |     })
259 | 
260 |     it('should start at error middleware declared after error', function(done){
261 |       app.use(function(err, req, res, next){
262 |         res.end('fail: ' + err.message);
263 |       });
264 |       app.use(function(req, res, next){
265 |         next(new Error('boom!'));
266 |       });
267 |       app.use(function(err, req, res, next){
268 |         res.end('pass: ' + err.message);
269 |       });
270 | 
271 |       request(app)
272 |         .get('/')
273 |         .expect(200, 'pass: boom!', done)
274 |     })
275 | 
276 |     it('should stack error fns', function(done){
277 |       app.use(function(req, res, next){
278 |         next(new Error('msg'));
279 |       })
280 |       app.use(function(err, req, res, next){
281 |         res.setHeader('X-Error', err.message);
282 |         next(err);
283 |       });
284 |       app.use(function(err, req, res, next){
285 |         res.end('got error ' + err.message);
286 |       });
287 | 
288 |       request(app)
289 |         .get('/')
290 |         .expect('X-Error', 'msg')
291 |         .expect(200, 'got error msg', done)
292 |     })
293 | 
294 |     it('should invoke error stack even when headers sent', function(done){
295 |       app.use(function(req, res, next){
296 |         res.end('0');
297 |         next(new Error('msg'));
298 |       });
299 |       app.use(function(err, req, res, next){
300 |         done();
301 |       });
302 | 
303 |       request(app)
304 |         .get('/')
305 |         .end(function () {})
306 |     })
307 |   })
308 | });
309 | 


--------------------------------------------------------------------------------
/test/server.js:
--------------------------------------------------------------------------------
  1 | 
  2 | var assert = require('assert');
  3 | var connect = require('..');
  4 | var http = require('http');
  5 | var rawrequest = require('./support/rawagent')
  6 | var request = require('supertest');
  7 | 
  8 | describe('app', function(){
  9 |   var app;
 10 | 
 11 |   beforeEach(function(){
 12 |     app = connect();
 13 |   });
 14 | 
 15 |   it('should inherit from event emitter', function(done){
 16 |     app.on('foo', done);
 17 |     app.emit('foo');
 18 |   });
 19 | 
 20 |   it('should work in http.createServer', function(done){
 21 |     var app = connect();
 22 | 
 23 |     app.use(function (req, res) {
 24 |       res.end('hello, world!');
 25 |     });
 26 | 
 27 |     var server = http.createServer(app);
 28 | 
 29 |     request(server)
 30 |       .get('/')
 31 |       .expect(200, 'hello, world!', done)
 32 |   })
 33 | 
 34 |   it('should be a callable function', function(done){
 35 |     var app = connect();
 36 | 
 37 |     app.use(function (req, res) {
 38 |       res.end('hello, world!');
 39 |     });
 40 | 
 41 |     function handler(req, res) {
 42 |       res.write('oh, ');
 43 |       app(req, res);
 44 |     }
 45 | 
 46 |     var server = http.createServer(handler);
 47 | 
 48 |     request(server)
 49 |       .get('/')
 50 |       .expect(200, 'oh, hello, world!', done)
 51 |   })
 52 | 
 53 |   it('should invoke callback if request not handled', function(done){
 54 |     var app = connect();
 55 | 
 56 |     app.use('/foo', function (req, res) {
 57 |       res.end('hello, world!');
 58 |     });
 59 | 
 60 |     function handler(req, res) {
 61 |       res.write('oh, ');
 62 |       app(req, res, function() {
 63 |         res.end('no!');
 64 |       });
 65 |     }
 66 | 
 67 |     var server = http.createServer(handler);
 68 | 
 69 |     request(server)
 70 |       .get('/')
 71 |       .expect(200, 'oh, no!', done)
 72 |   })
 73 | 
 74 |   it('should invoke callback on error', function(done){
 75 |     var app = connect();
 76 | 
 77 |     app.use(function (req, res) {
 78 |       throw new Error('boom!');
 79 |     });
 80 | 
 81 |     function handler(req, res) {
 82 |       res.write('oh, ');
 83 |       app(req, res, function(err) {
 84 |         res.end(err.message);
 85 |       });
 86 |     }
 87 | 
 88 |     var server = http.createServer(handler);
 89 | 
 90 |     request(server)
 91 |       .get('/')
 92 |       .expect(200, 'oh, boom!', done)
 93 |   })
 94 | 
 95 |   it('should work as middleware', function(done){
 96 |     // custom server handler array
 97 |     var handlers = [connect(), function(req, res, next){
 98 |       res.writeHead(200, {'Content-Type': 'text/plain'});
 99 |       res.end('Ok');
100 |     }];
101 | 
102 |     // execute callbacks in sequence
103 |     var n = 0;
104 |     function run(req, res){
105 |       if (handlers[n]) {
106 |         handlers[n++](req, res, function(){
107 |           run(req, res);
108 |         });
109 |       }
110 |     }
111 | 
112 |     // create a non-connect server
113 |     var server = http.createServer(run);
114 | 
115 |     request(server)
116 |       .get('/')
117 |       .expect(200, 'Ok', done)
118 |   });
119 | 
120 |   it('should escape the 500 response body', function(done){
121 |     app.use(function(req, res, next){
122 |       next(new Error('error!'));
123 |     });
124 |     request(app)
125 |       .get('/')
126 |       .expect(/Error: error!<br>/)
127 |       .expect(/<br> &nbsp; &nbsp;at/)
128 |       .expect(500, done)
129 |   })
130 | 
131 |   describe('404 handler', function(){
132 |     it('should escape the 404 response body', function(done){
133 |       rawrequest(app)
134 |         .get('/foo/<script>stuff\'n</script>')
135 |         .expect(404, />Cannot GET \/foo\/%3Cscript%3Estuff&#39;n%3C\/script%3E</, done)
136 |     });
137 | 
138 |     it('shoud not fire after headers sent', function(done){
139 |       var app = connect();
140 | 
141 |       app.use(function(req, res, next){
142 |         res.write('body');
143 |         res.end();
144 |         process.nextTick(next);
145 |       })
146 | 
147 |       request(app)
148 |         .get('/')
149 |         .expect(200, done)
150 |     })
151 | 
152 |     it('shoud have no body for HEAD', function(done){
153 |       var app = connect();
154 | 
155 |       request(app)
156 |         .head('/')
157 |         .expect(404)
158 |         .expect(shouldHaveNoBody())
159 |         .end(done)
160 |     })
161 |   })
162 | 
163 |   describe('error handler', function(){
164 |     it('should have escaped response body', function(done){
165 |       var app = connect();
166 | 
167 |       app.use(function(req, res, next){
168 |         throw new Error('<script>alert()</script>');
169 |       })
170 | 
171 |       request(app)
172 |         .get('/')
173 |         .expect(500, /&lt;script&gt;alert\(\)&lt;\/script&gt;/, done)
174 |     })
175 | 
176 |     it('should use custom error code', function(done){
177 |       var app = connect();
178 | 
179 |       app.use(function(req, res, next){
180 |         var err = new Error('ack!');
181 |         err.status = 503;
182 |         throw err;
183 |       })
184 | 
185 |       request(app)
186 |         .get('/')
187 |         .expect(503, done)
188 |     })
189 | 
190 |     it('should keep error statusCode', function(done){
191 |       var app = connect();
192 | 
193 |       app.use(function(req, res, next){
194 |         res.statusCode = 503;
195 |         throw new Error('ack!');
196 |       })
197 | 
198 |       request(app)
199 |         .get('/')
200 |         .expect(503, done)
201 |     })
202 | 
203 |     it('shoud not fire after headers sent', function(done){
204 |       var app = connect();
205 | 
206 |       app.use(function(req, res, next){
207 |         res.write('body');
208 |         res.end();
209 |         process.nextTick(function() {
210 |           next(new Error('ack!'));
211 |         });
212 |       })
213 | 
214 |       request(app)
215 |         .get('/')
216 |         .expect(200, done)
217 |     })
218 | 
219 |     it('shoud have no body for HEAD', function(done){
220 |       var app = connect();
221 | 
222 |       app.use(function(req, res, next){
223 |         throw new Error('ack!');
224 |       });
225 | 
226 |       request(app)
227 |         .head('/')
228 |         .expect(500)
229 |         .expect(shouldHaveNoBody())
230 |         .end(done)
231 |     });
232 |   });
233 | });
234 | 
235 | function shouldHaveNoBody () {
236 |   return function (res) {
237 |     assert.ok(res.text === '' || res.text === undefined)
238 |   }
239 | }
240 | 


--------------------------------------------------------------------------------
/test/support/env.js:
--------------------------------------------------------------------------------
1 | 
2 | process.env.NODE_ENV = 'test';
3 | 


--------------------------------------------------------------------------------
/test/support/rawagent.js:
--------------------------------------------------------------------------------
 1 | 'use strict'
 2 | 
 3 | var assert = require('assert')
 4 | var http = require('http')
 5 | 
 6 | module.exports = createRawAgent
 7 | 
 8 | function createRawAgent (app) {
 9 |   return new RawAgent(app)
10 | }
11 | 
12 | function RawAgent (app) {
13 |   this.app = app
14 | 
15 |   this._open = 0
16 |   this._port = null
17 |   this._server = null
18 | }
19 | 
20 | RawAgent.prototype.get = function get (path) {
21 |   return new RawRequest(this, 'GET', path)
22 | }
23 | 
24 | RawAgent.prototype._close = function _close (cb) {
25 |   if (--this._open) {
26 |     return process.nextTick(cb)
27 |   }
28 | 
29 |   this._server.close(cb)
30 | }
31 | 
32 | RawAgent.prototype._start = function _start (cb) {
33 |   this._open++
34 | 
35 |   if (this._port) {
36 |     return process.nextTick(cb)
37 |   }
38 | 
39 |   if (!this._server) {
40 |     this._server = http.createServer(this.app).listen()
41 |   }
42 | 
43 |   var agent = this
44 |   this._server.on('listening', function onListening () {
45 |     agent._port = this.address().port
46 |     cb()
47 |   })
48 | }
49 | 
50 | function RawRequest (agent, method, path) {
51 |   this.agent = agent
52 |   this.method = method
53 |   this.path = path
54 | }
55 | 
56 | RawRequest.prototype.expect = function expect (status, body, callback) {
57 |   var request = this
58 |   this.agent._start(function onStart () {
59 |     var req = http.request({
60 |       host: '127.0.0.1',
61 |       method: request.method,
62 |       path: request.path,
63 |       port: request.agent._port
64 |     })
65 | 
66 |     req.on('response', function (res) {
67 |       var buf = ''
68 | 
69 |       res.setEncoding('utf8')
70 |       res.on('data', function onData (s) { buf += s })
71 |       res.on('end', function onEnd () {
72 |         var err = null
73 | 
74 |         try {
75 |           assert.equal(res.statusCode, status, 'expected ' + status + ' status, got ' + res.statusCode)
76 | 
77 |           if (body instanceof RegExp) {
78 |             assert.ok(body.test(buf), 'expected body ' + buf + ' to match ' + body)
79 |           } else {
80 |             assert.equal(buf, body, 'expected ' + body + ' response body, got ' + buf)
81 |           }
82 |         } catch (e) {
83 |           err = e
84 |         }
85 | 
86 |         request.agent._close(function onClose () {
87 |           callback(err)
88 |         })
89 |       })
90 |     })
91 | 
92 |     req.end()
93 |   })
94 | }
95 | 


--------------------------------------------------------------------------------