{"id":13527755,"url":"https://github.com/h2non/rocky","last_synced_at":"2025-04-01T09:32:07.512Z","repository":{"id":33976403,"uuid":"37720488","full_name":"h2non/rocky","owner":"h2non","description":"Full-featured, middleware-oriented, programmatic HTTP and WebSocket proxy for node.js (deprecated)","archived":true,"fork":false,"pushed_at":"2021-04-21T13:41:24.000Z","size":508,"stargazers_count":371,"open_issues_count":14,"forks_count":28,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-05-09T23:53:27.803Z","etag":null,"topics":["balancer","forward","forward-proxy","gateway","http-proxy","microservice","middleware","proxy","replay","replay-requests"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"valentimaraujo/EvoDevWebmotorsCrawler","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/h2non.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-19T12:28:47.000Z","updated_at":"2024-01-13T23:53:57.000Z","dependencies_parsed_at":"2022-07-13T17:10:32.490Z","dependency_job_id":null,"html_url":"https://github.com/h2non/rocky","commit_stats":null,"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Frocky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Frocky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Frocky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Frocky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/h2non","download_url":"https://codeload.github.com/h2non/rocky/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246616466,"owners_count":20806144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["balancer","forward","forward-proxy","gateway","http-proxy","microservice","middleware","proxy","replay","replay-requests"],"created_at":"2024-08-01T06:01:59.923Z","updated_at":"2025-04-01T09:32:06.767Z","avatar_url":"https://github.com/h2non.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Proxies","proxy","Packages","包","📦 Legacy \u0026 Inactive Projects"],"sub_categories":["HTTP"],"readme":"# rocky [![Build Status](https://api.travis-ci.org/h2non/rocky.svg?branch=master\u0026style=flat)](https://travis-ci.org/h2non/rocky) [![Code Climate](https://codeclimate.com/github/h2non/rocky/badges/gpa.svg)](https://codeclimate.com/github/h2non/rocky) [![NPM](https://img.shields.io/npm/v/rocky.svg)](https://www.npmjs.org/package/rocky) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com) [![jsdoc-reference](https://img.shields.io/badge/jsdoc-reference-blue.svg)](http://jsdocs.herokuapp.com/github.com/h2non/rocky)\n\n\u003cimg align=\"right\" height=\"160\" src=\"http://s22.postimg.org/f0jmde7o1/rocky.jpg\" /\u003e\n\nA multipurpose, **full-featured**, **middleware-oriented** and **hackable** **HTTP/S** and **WebSocket proxy** with powerful built-in features such as **versatile routing layer**, **traffic interceptor and replay** to multiple backends, built-in **balancer**, traffic **retry/backoff** logic, **hierarchical configuration**, among [others](#features).\nBuilt for [node.js](http://nodejs.org)/[io.js](https://iojs.org).\n\n**rocky** can be fluently used [programmatically](#programmatic-api) or via [command-line](#command-line) interface.\nIt's framework agnostic, but you can optionally plug in with [connect](https://github.com/senchalabs/connect)/[express](http://expressjs.com) apps.\n\nTo get started, take a look to [how does it work](#how-does-it-work), [basic usage](#usage), [middleware layer](#middleware-layer) and [examples](/examples).\n\n**Note**: `retry` feature is temporary not available in latest `node.js` versions.\n\n## Contents\n\n- [Features](#features)\n- [When rocky can be useful?](#when-rocky-can-be-useful)\n- [Installation](#installation)\n- [Benchmark](#benchmark)\n- [About](#about)\n  - [Versions](#versions)\n  - [How does it work?](#how-does-it-work)\n  - [Projects using rocky](#projects-using-rocky)\n- [Middleware layer](#middleware-layer)\n  - [Hierarchies](#hierarchies)\n  - [Types of middleware](#types-of-middleware)\n  - [Middleware flow](#middleware-flow)\n  - [Middleware API](#middleware-api)\n  - [Third-party middleware](#third-party-middleware)\n- [Command-line](#command-line)\n  - [Installation](#installation-1)\n  - [Usage](#usage)\n  - [Examples](#examples)\n  - [Configuration file](#configuration-file)\n- [Programmatic API](#programmatic-api)\n  - [Usage](#usage)\n  - [Configuration](#configuration)\n  - [Documentation](#rocky-options-)\n  - [Supported events](#events)\n- [Special thanks](#special-thanks)\n\n## Features\n\n- Full-featured HTTP/S proxy (backed by [http-proxy](https://github.com/nodejitsu/node-http-proxy))\n- Supports WebSocket protocol proxy (replay not supported yet)\n- Able to replay traffic to multiple backends (concurrently or sequentially)\n- Able to intercept HTTP requests and responses and modify them on-the-fly\n- Featured built-in path based router with params matching\n- Built-in load balancer\n- Built-in HTTP traffic retry/backoff\n- Nested configuration per global/route scopes and forward/replay phases\n- Hierarchical middleware layer supporting different HTTP traffic flow phases\n- Easily integrable with connect/express via middleware\n- Able to run as standalone HTTP/S server (no connect/express, uses `http` module)\n- Compatible with most of the existent connect/express middleware\n- Powerful programmatic control supporting dynamic configurations and zero-downtime\n- Supports both concurrent and sequential HTTP traffic flow modes\n- Small hackable core designed for extensibility\n- Fluent, elegant and evented [programmatic API](#programmatic-api)\n- Provides a [command-line interface](https://github.com/h2non/rocky-cli) with declarative [configuration file](#configuration-file)\n- Handles properly `gzip` responses, especially when intercepting payloads\n\n## When `rocky` can be useful?\n\n- As intermediate proxy for service migrations (e.g: APIs)\n- Replaying traffic to one or multiple backends\n- As reverse proxy to forward traffic to one o multiple servers.\n- As Man-in-the-Middle proxy intercepting and transforming the request/response on-the-fly\n- As intermediate HTTP proxy adapter for external services integrations\n- As HTTP [API gateway](http://microservices.io/patterns/apigateway.html)\n- As standard reverse HTTP proxy with dynamic routing\n- As security proxy layer\n- As dynamic HTTP load balancer with programmatic control\n- As embedded HTTP proxy in your node.js app\n- As HTTP cache or log server\n- As SSL terminator proxy\n- As HTTP proxy for performance testing\n- As traditional forward HTTP proxy (e.g: Squid)\n- For HTTP session manipulation and debugging\n- For HTTP traffic recording and inspection\n- For A/B testing\n- For fuzz testing (see [toxy](https://github.com/h2non/toxy))\n- As intermediate test server intercepting and generating random/fake responses\n- And whatever a programmatic HTTP proxy can be useful to\n\n## Installation\n\n```bash\nnpm install rocky --save\n```\n\n## Benchmark\n\nSee [benchmark/README.md](https://github.com/h2non/rocky/tree/master/benchmark#results) for detailed benchmark results.\n\n## About\n\n### Versions\n\n- [**0.1.x**](https://github.com/h2non/rocky/tree/v0.1.x) - First version. Initially released at `25.06.2015`. Beta\n- [**0.2.x**](https://github.com/h2non/rocky/tree/v0.2.x) - Released at `07.07.2015`. Major features and stability improvements.\n- [**0.3.x**](https://github.com/h2non/rocky/tree/v0.3.x) - Released at `24.07.2015`. Production-focused version.\n- [**0.4.x**](https://github.com/h2non/rocky/tree/master) - Released at `02.10.2015`. Introduces WebSocket support and other minor features. Stable \u0026 actively maintained. Recommended version.\n\n### How does it work?\n\n```\n         |==============|\n         | HTTP clients |\n         |==============|\n               ||||\n         |==============|\n         |  HTTP proxy  |   -\u003e  Via the built-in HTTP server or via connect/express\n         |~~~~~~~~~~~~~~|\n         | Rocky Router |   -\u003e  The built-in featured router matches the proper route\n         |~~~~~~~~~~~~~~|\n         |  Middleware  |   -\u003e  Dispatch the hierarchical middleware layer\n         |==============|\n            ||      |\n  (duplex) //        \\ (one-way)\n         //            \\\n   /----------\\   /----------\\    /----------\\\n   |  target  |   | replay 1 | -\u003e | replay 2 | (*N)\n   \\----------/   \\----------/    \\----------/\n```\n\n### Projects using rocky\n\n- [toxy](https://github.com/h2non/toxy) - Hackable HTTP proxy to simulate server failures and network conditions.\n- [balboa](https://github.com/h2non/balboa) - Simple, hackable HTTP forward proxy.\n\nOpen an issue or send a PR to add your project!\n\n## Middleware layer\n\nOne of the most powerful features in `rocky` is its build-in domain specific middleware, based on `connect/express` middleware.\n\nThe middleware layer provides a simple and consistent way to augment the proxy functionality very easily, allowing you to attach third-party middleware (also known as plugins) to cover specific tasks which acts between different phases of the proxy, for instance handling incoming/outgoing traffic.\n\n`rocky` middleware layer has the same interface as connect/express middleware, and it's mostly compatible with existent middleware (see [express](https://github.com/h2non/rocky/blob/master/examples/express.js) example).\n\n### Hierarchies\n\n`rocky` supports multiple middleware hierarchies:\n\n- **global** - Dispatched on every incoming request matched by the router\n- **route** - Dispatched only at route scope\n\n### Types of middleware\n\n`rocky` introduces multiple types of middleware layers based on the same interface and behavior of connect/express middleware.\nThis was introduced in order to achieve in a more responsive way multiple traffic flows in the specific scope\nand behavior nature of a programmatic HTTP proxy with traffic replay.\n\nThose flows are intrinsically correlated but might be handled in a completely different way.\nThe goal is to allowing you to handle them accordingly, acting in the middle of those phases to augment some functionality or react to some event with better accuracy.\n\n**Supported types of middleware**:\n\n##### router\n\n- **Scope**: `global`\n- **Description**: Dispatched on every matched route.\n- **Notation**: `.use([path], function (req, res, next))`\n\n##### forward\n\n- **Scope**: `global`, `route`\n- **Description**: Dispatched before forwarding an incoming request.\n- **Notation**: `.useForward(function (req, res, next))`\n\n##### replay\n\n- **Scope**: `global`, `route`\n- **Description**: Dispatched before starting each replay request.\n- **Notation**: `.useReplay(function (req, res, next))`\n\n##### response\n\n- **Scope**: `global`, `route`\n- **Description**: Dispatched on server response. Only applicable in `forward` traffic.\n- **Notation**: `.useResponse(function (req, res, next))`\n\n##### param\n\n- **Scope**: `global`\n- **Description**: Dispatched on every matched param on any route.\n- **Notation**: `.useParam(function (req, res, next))`\n\n### Middleware flow\n\nMiddleware functions are always executed in FIFO order.\nThe following diagram represents the internal incoming request flow and how the different middleware layers are involved on it:\n\n```\n↓    ( Incoming request )   ↓\n↓            |||            ↓\n↓      ----------------     ↓\n↓      |    Router    |     ↓ --\u003e Match a route, dispatching its middleware if required\n↓      ----------------     ↓\n↓            |||            ↓\n↓   ---------------------   ↓\n↓   | Global middleware |   ↓ --\u003e Dispatch on every incoming request (router, param)\n↓   ---------------------   ↓\n↓            |||            ↓\n↓           /   \\           ↓\n↓         /       \\         ↓\n↓       /           \\       ↓\n↓ [ Forward ]    [ Replay ] ↓ --\u003e Dispatch both middleware in separated flows (route forward and replay)\n↓      \\             /      ↓\n↓       \\           /       ↓\n↓        \\         /        ↓\n↓    -------------------    ↓\n↓    | HTTP dispatcher |    ↓ --\u003e Send requests over the network (concurrently or sequentially)\n↓    -------------------    ↓\n```\n\n### Middleware API\n\nMiddleware layer behaves and has the same interface as connect/express.\nIn other words, you can create or use middleware as you already know with the typical notation `function(req, res, next)`\n\nAs a kind of inversion of control, `rocky` exposes a tiny API in every `http.ClientRequest` passed via the middleware layer:\n\n##### Request\n\n- **req.rocky** `object`\n  - **.options** `object` - Exposes the [configuration](#configuration) options for the current request.\n  - **.proxy** `Rocky` - Exposes the rocky instance. Use only for hacking purposes!\n  - **.route** `Route` - Exposes the current running route. Only available in `route` type middleware\n- **req.stopReplay** `boolean` - Optional field internally checked by `rocky` to stop the request replay process.\n\n##### Response\n\n- **res.rocky** `object`\n  - **.options** `object` - Exposes the [configuration](#configuration) options for the current request.\n  - **.proxy** `Rocky` - Exposes the rocky instance. Use only for hacking purposes!\n  - **.route** `Route` - Exposes the current running route. Only available in `route` type middleware\n\nExample replacing the target server URL:\n```js\nrocky()\n  .get('/users/:name')\n  .forward('http://old.server.net')\n  .use(function (req, res, next) {\n    if (req.params.name === 'admin') {\n      // Overwrite the target URL only for this user\n      req.rocky.options.target = 'http://new.server.net'\n    }\n    next()\n  })\n```\n\n### Third-party middleware\n\n- [**consul**](https://github.com/h2non/rocky-consul) - Dynamic service discovery and balancing using Consul\n- [**vhost**](https://github.com/h2non/rocky-vhost) - vhost based proxy routing for rocky\n- [**version**](https://github.com/h2non/rocky-version) - HTTP API version based routing (uses [http-version](https://github.com/h2non/http-version))\n\nNote that you can use any other existent middleware plug in `rocky` as part of your connect/express app.\n\nAdditionally, `rocky` provides some [built-in middleware functions](#rockymiddleware-1) that you can plug in different types of middleware.\n\n## Command-line\n\n### Installation\n\nFor command-line usage, you must install [`rocky-cli`](https://github.com/h2non/rocky-cli)\n```\nnpm install -g rocky-cli\n```\n\n### Usage\n\n```bash\nStart rocky HTTP proxy server\nUsage: rocky [options]\n\nOptions:\n  --help, -h     Show help                                             [boolean]\n  --config, -c   File path to TOML config file\n  --port, -p     rocky HTTP server port\n  --forward, -f  Default forward server URL\n  --replay, -r   Define a replay server URL\n  --route, -t    Define one or multiple routes, separated by commas\n  --key, -k      Path to SSL key file\n  --cert, -e     Path to SSL certificate file\n  --secure, -s   Enable SSL certification validation\n  --balance, -b  Define server URLs to balance between, separated by commas\n  --mute, -m     Disable HTTP traffic log in stdout                    [boolean]\n  --debug, -d    Enable debug mode                                     [boolean]\n  -v, --version  Show version number                                   [boolean]\n\nExamples:\n  rocky -c rocky.toml \\\n  -f http://127.0.0.1:9000 \\\n  -r http://127.0.0.1\n```\n\n#### Examples\n\nPassing the config file:\n```\nrocky --config rocky.toml --port 8080\n```\n\nReading config from `stdin`:\n```\ncat rocky.toml | rocky --port 8080\n```\n\nTransparent `rocky.toml` file discovery in current and higher directories:\n```\nrocky --port 8080\n```\n\nAlternatively `rocky` can find the config file passing the `ROCKY_CONFIG` environment variable:\n```\nROCKY_CONFIG=path/to/rocky.toml rocky --port 8080\n```\n\nOr for simple configurations you can setup a proxy without a config file, defining the routes via flag:\n```\nrocky --port --forward http://server --route \"/download/*, /images/*, /*\"\n```\n\n### Configuration file\n\nDefault configuration file name: `rocky.toml`\n\nThe configuration file must be declared in [TOML](https://github.com/toml-lang/toml) language\n```toml\nport = 8080\nforward = \"http://google.com\"\nreplay = [\"http://duckduckgo.com\"]\n\n[ssl]\ncert = \"server.crt\"\nkey  = \"server.key\"\n\n[\"/users/:id\"]\nmethod = \"all\"\nforward = \"http://new.server\"\n\n[\"/oauth\"]\nmethod = \"all\"\nforward = \"http://auth.server\"\n\n[\"/*\"]\nmethod = \"GET\"\nforward = \"http://old.server\"\n\n[\"/download/:file\"]\nmethod = \"GET\"\ntimeout = 5000\nbalance = [\"http://1.file.server\", \"http://2.file.server\"]\n\n[\"/photo/:name\"]\nmethod = \"GET\"\nreplayAfterForward = true\n[[replay]]\n  target = \"http://old.server\"\n  forwardHost = true\n[[replay]]\n  target = \"http://backup.server\"\n```\n\n## Programmatic API\n\n### Usage\n\nExample using [Express](http://expressjs.com)\n```js\nvar rocky = require('rocky')\nvar express = require('express')\n\n// Set up the express server\nvar app = express()\n// Set up the rocky proxy\nvar proxy = rocky()\n\n// Default proxy config\nproxy\n  .forward('http://new.server')\n  .replay('http://old.server')\n  .replay('http://log.server')\n  .options({ forwardHost: true })\n\n// Configure the routes to forward/replay\nproxy\n  .get('/users/:id')\n\nproxy\n  .get('/download/:file')\n  .balance(['http://1.file.server', 'http://2.file.server'])\n\n// Plug in the rocky middleware\napp.use(proxy.middleware())\n\n// Old route (won't be called since it will be intercepted by rocky)\napp.get('/users/:id', function () { /* ... */ })\n\napp.listen(3000)\n```\n\nExample using the built-in HTTP server\n```js\nvar rocky = require('rocky')\n\nvar proxy = rocky()\n\n// Default proxy config\nproxy\n  .forward('http://new.server')\n  .replay('http://old.server', { replayOriginalBody: true })\n  .options({ forwardHost: true })\n  .on('proxy:error', function (err) {\n    console.error('Error:', err)\n  })\n  .on('proxyReq', function (proxyReq, req, res, opts) {\n    console.log('Proxy request:', req.url, 'to', opts.target)\n  })\n  .on('proxyRes', function (proxyRes, req, res) {\n    console.log('Proxy response:', req.url, 'with status', res.statusCode)\n  })\n\n// Configure the routes to forward/replay\nproxy\n  .get('/users/:id')\n  // Overwrite the path\n  .toPath('/profile/:id', { id: '0123' })\n  // Add custom headers\n  .headers({\n    'Authorization': 'Bearer 0123456789'\n  })\n\nproxy\n  .get('/search')\n  // Overwrite the forward URL for this route\n  .forward('http://another.server')\n  // Use a custom middleware for validation purposes\n  .use(function (req, res, next) {\n    if (req.headers['Authorization'] !== 'Bearer 012345678') {\n      res.statusCode = 401\n      return res.end()\n    }\n    next()\n  })\n  // Intercept and transform the response body before sending it to the client\n  .transformResponseBody(function (req, res, next) {\n    // Get the body buffer and parse it (assuming it's a JSON)\n    var body = JSON.parse(res.body.toString())\n\n    // Compose the new body\n    var newBody = JSON.stringify({ salutation: 'hello ' + body.hello })\n\n    // Send the new body in the request\n    next(null, newBody)\n  })\n\nproxy.listen(3000)\n```\n\nFor more usage cases, take a look to the [examples](/examples)\n\n### Configuration\n\n**Supported configuration params**:\n\n- **forward** `string` - Default forward URL\n- **debug** `boolean` - Enable debug mode. Default `false`\n- **target** `string` - \u003curl string to be parsed with the url module\n- **replay** `array\u003cstring|object\u003e` - Optional replay server URLs. You can use the `replay()` method to configure it\n- **ws** `boolean` - Enable WebSocket proxy mode.\n- **balance** `array\u003curl\u003e` - Define the URLs to balance. Via API you should use the `balance()` method\n- **timeout** `number` - Timeout for request socket\n- **proxyTimeout** `number` - Timeout for proxy request socket\n- **retry** `object` - Enable retry/backoff logic for forward/replay traffic. See [allowed params](https://github.com/tim-kos/node-retry#retrytimeoutsoptions). Default: `null`\n- **replayRetry** `object` - Enable retry logic for replay traffic with custom options. Default: `null`\n- **agent** `object` - object to be passed to http(s).request. See node.js [`https`](https://nodejs.org/api/https.html#https_class_https_agent) docs\n- **ssl** `object` - object to be passed to https.createServer()\n  - **cert** `string` - Path to SSL certificate file\n  - **key** `string` - Path to SSL key file\n- **ws** `boolean` - true/false, if you want to proxy websockets\n- **xfwd** `boolean` - true/false, adds x-forward headers\n- **secure** `boolean` - true/false, verify SSL certificate\n- **toProxy** `boolean` - true/false, explicitly specify if we are proxying to another proxy\n- **prependPath** `boolean` - true/false, Default: true - specify whether you want to prepend the target's path to the proxy path\n- **ignorePath** `boolean` - true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request\n- **localAddress** `boolean` - \u003cLocal interface string to bind for outgoing connections\n- **changeOrigin** `boolean` - \u003ctrue/false, Default: false - **changes** the origin of the host header to the target URL\n- **auth** `string` - Basic authentication i.e. 'user:password' to compute an Authorization header.\n- **hostRewrite** `string` - rewrites the location hostname on (301/302/307/308) redirects, Default: null.\n- **autoRewrite** `boolean` - rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.\n- **protocolRewrite** `string` - rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.\n- **forwardOriginalBody** `boolean` - Only valid for **forward** request. Forward the original body instead of the transformed one.\n- **replayOriginalBody** `boolean` - Only valid for **replay** request. Forward the original body instead of the transformed one.\n- **router** `object` - Specific router params\n  - **strict** `boolean` - When `false` trailing slashes are optional (default: `false`)\n  - **caseSensitive** `boolean` - When `true` the routing will be case sensitive. (default: `false`)\n  - **mergeParams** `boolean` - When `true` any `req.params` passed to the router will be\n    merged into the router's `req.params`. (default: `false`)\n\n### rocky([ options ])\n\nCreates a new rocky instance with the given options.\n\nYou can pass any of the allowed params at [configuration](#configuration) level and any supported [http-proxy options](https://github.com/nodejitsu/node-http-proxy/blob/master/lib/http-proxy.js#L33-L50)\n\n#### rocky#forward(url)\nAliases: `target`, `forwardTo`\n\nDefine a default target URL to forward the request\n\n#### rocky#replay(url, [ opts ])\nAlias: `replayTo`\n\nAdd a server URL to replay the incoming request\n\n`opts` param provide specific replay [options](#configuration), overwritting the parent options.\n\nNote: replay feature is only valid for HTTP traffic.\n\n#### rocky#options(options)\n\nDefine/overwrite rocky server [options](#configuration).\nYou can pass any of the [supported options](https://github.com/nodejitsu/node-http-proxy/blob/master/lib/http-proxy.js#L33-L50) by `http-proxy`.\n\n#### rocky#protocol(name)\n\nDefine the proxy protocol operation mode.\nSupported options are: `http`, `ws`\n\n#### rocky#use([ path ], ...middleware)\nAlias: `useIncoming`\n\nUse the given middleware to handle **all http methods** on the given path, defaulting to the root path.\n\n#### rocky#useParam(param, ...middleware)\nAlias: `param()`\n\nMaps the specified path parameter name to a specialized param-capturing middleware.\nThe middleware stack is the same as `.use()`.\n\nNote: this middleware is only valid for HTTP traffic.\n\n#### rocky#useReplay(...middleware)\n\nUse a middleware for all the incoming traffic in the HTTP replay phase.\nThis middleware stack can be useful to differ between forward/replay traffic, applying separated flows of middleware.\n\nNote: this middleware is only valid for HTTP traffic.\n\n#### rocky#useForward(...middleware)\n\nUse a middleware for all the incoming traffic only for the HTTP request forward phase.\n\nFor most cases you will only use `.use()`, but for particular modifications only for the forwarded traffic, this middleware can be useful.\n\nNote: this middleware is only valid for HTTP traffic.\n\n#### rocky#useResponse(...middleware)\nAlias: `useOutgoing`\n\nUse a middleware for the outgoing response traffic of the forwarded request.\n\nThis middleware stack is useful to handle intercept and modify server responses before sending it to the end client in the other side of the proxy.\n\nNote: this middleware is only valid for HTTP traffic.\n\n#### rocky#useWs(...middleware)\n\nUse a WebSocket specific middleware. Middleware chain will be executed on every incoming WebSocket connection.\n\n#### rocky#useFor(name, ...middleware)\n\nUse a custom middleware for a specific phase. Supported phase names are: `forward`, 'replay'.\n\nThis method is used internally, however it's also public since it could be useful\nfor dynamic middleware configurations instead of using the shortcut methods such as: `useReplay` or `useForward`.\n\n#### rocky#balance(...urls)\n\nDefine a set of URLs to balance between with a simple round-robin like scheduler.\n\n#### rocky#stopReplay()\n\nDisable replay logic.\n\n#### rocky#retry([ opts, filter ])\n\nEnable and define a custom retry logic as global configuration.\nSee [`Route#retry`](#routeretry-opts-filter-) for details.\n\n#### rocky#on(event, handler)\n\nSubscribe to a proxy event.\nSee support events [here](#events)\n\n#### rocky#once(event, handler)\n\nRemove an event by its handler function.\nSee support events [here](#events)\n\n#### rocky#off(event, handler)\n\nRemove an event by its handler function.\nSee support events [here](#events)\n\n#### rocky#removeAllListeners(event)\n\nRemove all the subscribers to the given event.\nSee support events [here](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events)\n\n#### rocky#middleware()\nReturn: `Function(req, res, next)`\n\nReturn a connect/express compatible middleware\n\n#### rocky#requestHandler(req, res, next)\n\nRaw HTTP request/response handler.\n\n#### rocky#listen(port, [ host ])\n\nStarts a HTTP proxy server in the given port\n\n#### rocky#close([ callback ])\n\nClose the HTTP proxy server, if exists.\nShortcut to `rocky#server.close(cb)`\n\n#### rocky#all(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nAdd a route handler for the given path for all HTTP methods\n\n#### rocky#route(method, path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\n#### rocky#get(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nConfigure a new route the given path with `GET` method\n\n#### rocky#post(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nConfigure a new route the given path with `POST` method\n\n#### rocky#put(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nConfigure a new route the given path with `PUT` method\n\n#### rocky#delete(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nConfigure a new route the given path with `DELETE` method\n\n#### rocky#patch(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nConfigure a new route the given path with `PATCH` method\n\n#### rocky#head(path, [ ...middleware ])\nReturn: [`Route`](#routepath)\n\nConfigure a new route the given path with `HEAD` method\n\n#### rocky#routeAll()\nReturn: [`Route`](#routepath)\n\nRoute all the incoming traffic to the default target.\nThis is a shortcut to `rocky#all('/*')`.\n\n**Note**: you must call this method only when you already defined other routes.\n\n#### rocky#query([ params | parseFn ])\n\nParse and expose the query params in `http.IncomingMessage` object via `req.query = Object`.\n\nAdditionally you can pass an `object` with additional params to add or a middleware `function(req, res, next)` to work in details with query params.\n\n#### rocky#headers(headers)\n\nAdd/extend custom headers to the incoming request before forward/replay it.\n\n#### rocky#timeout(milliseconds)\n\nDefine a custom timeout for forward/replay traffic in milliseconds.\n\n#### rocky#router\n\nInternal [router](https://github.com/pillarjs/router#routeroptions) instance\n\n#### rocky#server\n\n[HTTP](https://nodejs.org/api/http.html)/[HTTPS](https://nodejs.org/api/https.html) server instance.\nOnly present if `listen()` was called starting the built-in server.\n\n#### rocky#mw = MiddlewarePool\n\nExposes the [MiddlewarePool](#rockymiddlewarepool) instance.\n\n### Route(path)\n\n#### route#forward(url)\nAliases: `target`, `forwardTo`\n\nOverwrite forward server for the current route.\n\n#### route#replay(url, [ opts ])\nAlias: `replyTo`\n\nOverwrite replay servers for the current route.\n\n`opts` param provide specific replay [options](#configuration), overwritting the parent options.\n\nNote: replay feature is only valid for HTTP traffic.\n\n#### route#balance(urls)\n\nDefine a set of URLs to balance between with a simple round-robin like scheduler.\n`urls` param must be an array of strings.\n\n#### route#stopReplay()\n\nDisable replay logic for the current route.\n\n#### route#reply(status, [ headers, body ])\n\nShortcut method to intercept and reply the incoming request.\nIf used, `body` param must be a `string` or `buffer`\n\n#### route#unregister()\n\nUnregister the current route.\nIf the route if matched by the router, it will be ignored, continuing to the next route in the stack.\n\n#### route#timeout(milliseconds)\n\nDefine a custom timeout for forward/replay traffic in milliseconds.\n\n#### route#toPath(url, [ params ])\n\nOverwrite the request path, defining additional optional params.\n\n#### route#headers(headers)\n\nDefine or overwrite request headers for the current route.\n\n#### route#query([ params | parseFn ])\n\nParse and expose the query params in `http.IncomingMessage` object via `req.query = Object`.\n\nAdditionally you can pass an `object` with additional params to add or a middleware `function(req, res, next)` to work in details with query params.\n\n#### route#host(host)\n\nOverwrite the `Host` header value when forward the request.\n\n#### route#redirect(url)\n\nRedirect the incoming request for the current route.\n\n#### route#replayAfterForward([ filter ])\nAlias: `sequential`\n\nDispatch the replay phase after the forward request ends (either with success or fail status).\n\nNote: this will buffer all the body data. Avoid using it with large payloads\n\n#### route#replaySequentially([ filter ])\n\nEnable sequential replay process executed in FIFO order: if some replay request fails, the queue is empty and the process will stop\n\nNote: this will buffer all the body data. Avoid using it with large payloads\n\n#### route#retry([ opts, filter ])\n\nEnable retry logic for forward traffic. See allowed options [here](https://github.com/tim-kos/node-retry#retrytimeoutsoptions).\nYou can also define additional retry validations passing an array of function via `strategies` field in `opts` object argument.\n\nNote: enabling retry logic will forces buffering all the body payload. Be careful when using it with large payloads\n\n```js\nvar customRetryStrategies = [\n  function invalidCodes(err, res) {\n    return !err \u0026\u0026 [404, 406].indexOf(res.statusCode) !== -1\n  }\n]\n\nrocky()\n  .get('/download/:id')\n  .retry({\n    retries: 3,\n    factor: 2,\n    minTimeout: 100,\n    maxTimeout: 30 * 1000,\n    randomize: true,\n    strategies: customRetryStrategies\n  })\n\nrocky.forward('http://inconsistent-server')\n```\n\n#### route#bufferBody([ filter ])\nAlias: `interceptBody`\n\nIntercept and cache in a buffer the request payload data.\nBody will be exposed in `req.body`.\n\nNote: use it only for small payloads, since the whole body will be buffered in memory\n\n#### route#transformRequest(middleware, [ filter ])\nAlias: `transformRequestBody()`\n\nThis method implements a non-instrusive native `http.IncomingMessage` stream wrapper that allow you to intercept and transform the request body received from the client before sending it to the target server.\n\nThe `middleware` argument must a function which accepts the following arguments: `function(req, res, next)`\nThe `filter` arguments is optional and it can be a `string`, `regexp` or `function(req)` which should return `boolean` if the `request` passes the filter. The default check value by `string` or `regexp` test is the `Content-Type` header.\n\nIn the middleware function **must call the `next` function**, which accepts the following arguments: `err, newBody, encoding`\nYou can see an usage example [here](/examples/interceptor.js).\n\n**Caution**: using this middleware could generate in some scenarios negative performance side-effects, since the whole payload data will be buffered in the heap until it's finished. Don't use it if you need to handle large payloads.\n\nThe body will be exposed as raw `Buffer` or `String` on both properties `body` and `originalBody` in `http.ClientRequest`:\n```js\nrocky\n  .post('/users')\n  .transformRequest(function (req, res, next) {\n    // Get the body buffer and parse it (assuming it's a JSON)\n    var body = JSON.parse(req.body.toString())\n\n    // Compose the new body\n    var newBody = JSON.stringify({ salutation: 'hello ' + body.hello })\n\n    // Set the new body\n    next(null, newBody, 'utf8')\n  }, function (req) {\n    // Custom filter\n    return /application\\/json/i.test(req.headers['content-type'])\n  })\n```\n\n#### route#transformResponse(middleware, [ filter ])\nAlias: `transformResponseBody()`\n\nThis method implements a non-instrusive native `http.RequestResponse` stream wrapper that allow you to intercept and transform the response body received from the target server before sending it to the client.\n\nThe `middleware` argument must a function which accepts the following arguments: `function(req, res, next)`\nThe `filter` arguments is optional and it can be a `string`, `regexp` or `function(res)` which should return `boolean` if the `request` passes the filter. The default check value by `string` or `regexp` test is the `Content-Type` header.\n\nIn the middleware function **must call the `next` function**, which accepts the following arguments: `err, newBody, encoding`\nYou can see an usage example [here](/examples/interceptor.js).\n\n**Caution**: using this middleware could generate in some scenarios negative performance side-effects since the whole payload data will be buffered in the heap until it's finished. Don't use it if you need to handle large payloads.\n\nThe body will be exposed as raw `Buffer` or `String` on both properties `body` and `originalBody` in `http.ClientResponse`:\n```js\nrocky\n  .post('/users')\n  .transformResponse(function (req, res, next) {\n    // Get the body buffer and parse it (assuming it's a JSON)\n    var body = JSON.parse(res.body.toString())\n\n    // Compose the new body\n    var newBody = JSON.stringify({ salutation: 'hello ' + body.hello })\n\n    // Set the new body\n    next(null, newBody, 'utf8')\n  }, function (res) {\n    // Custom filter\n    return /application\\/json/i.test(res.getHeader('content-type'))\n  })\n```\n\n#### route#options(options)\n\nOverwrite default proxy [options](#configuration) for the current route.\nYou can pass any supported option by [http-proxy](https://github.com/nodejitsu/node-http-proxy/blob/master/lib/http-proxy.js#L33-L50)\n\n#### route#use(...middleware)\nAlias: `useIncoming`\n\nUse a middleware for the incoming traffic for the current route for both replay/forward phases.\n\n#### route#useReplay(...middleware)\n\nUse a middleware for current route incoming traffic in the HTTP replay phase.\nThis middleware stack can be useful to differ between forward/replay traffic, applying separated flows of middleware.\n\n#### route#useForward(...middleware)\n\nUse a middleware for current route incoming traffic only for the HTTP request forward phase.\nFor most cases you will only use `.use()`, but for particular modifications only for the forwarded traffic, this middleware can be useful.\n\n#### route#useFor(name, ...middleware)\n\nThis method is used internally, however it's also public since it could be useful\nfor dynamic middleware configurations instead of using the shortcut methods such as: `useReplay` or `useForward`.\n\n#### route#on(event, ...handler)\n\nSubscribes to a specific event for the given route.\nUseful to intercept the status or modify the options on-the-fly\n\n##### Events\n\n- **proxyReq** `opts, proxyReq, req, res` - Fired when the request forward starts\n- **proxyRes** `opts, proxyRes, req, res` - Fired when the target server respond\n- **proxy:response** `req, res` - Fired when the proxy receives the response from the server\n- **proxy:error** `err, req, res` - Fired when the proxy request fails\n- **proxy:retry** `err, req, res` - Fired before perform a retry request attempt\n- **replay:start** `params, opts, req` - Fired before a replay request starts\n- **replay:error** `opts, err, req, res` - Fired when a replay request fails\n- **replay:end** `params, opts, req` - Fired when a replay request ends\n- **replay:stop** `params, opts, req` - Fired when a replay request process is stopped\n- **replay:retry** `err, req, res` - Fired before perform a retry request attempt for replay traffic\n- **server:error** `err, req, res` - Fired on server middleware error. Only available if running as standalone HTTP server\n- **route:missing** `req, res` - Fired on missing route. Only available if running as standalone HTTP server\n\nFor more information about events, see the [events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events) fired by `http-proxy`\n\n#### route#once(event, ...handler)\n\nSubscribes to a specific event for the given route, and unsubscribes after dispatched\n\n#### route#off(event, handler)\n\nRemove an event by its handler function in the current route\n\n#### route#mw = MiddlewarePool\n\nExposes the [MiddlewarePool](#rockymiddlewarepool) instance used for the route scope.\n\n### rocky.middleware\n\nExpose the built-in internal middleware [functions](/lib/middleware).\n\nYou can reuse them as standard middleware in different ways, like this:\n```js\nrocky()\n  .all('/*')\n  .use(rocky.middleware.headers({\n    'Authorization': 'Bearer 0123456789'\n  }))\n  .useReplay(rocky.middleware.host('replay.server.net'))\n```\n\n#### rocky.middleware.requestBody(middleware)\n\nIntercept and optionally transform/replace the request body before forward it to the target server.\n\nSee [rocky#transformRequestBody](#routetransformrequestmiddleware--filter-) for more details.\n\n#### rocky.middleware.responseBody(middleware)\n\nIntercept and optionally transform/replace the response body from the server before send it to the client.\n\nSee [rocky#transformResponseBody](#routetransformresponsemiddleware--filter-) for more details.\n\n#### rocky.middleware.toPath(path, [ params ])\n\nOverrites the request URL path of the incoming request before forward/replay it.\n\n#### rocky.middleware.headers(headers)\n\nAdd/extend custom headers to the incoming request before forward/replay it.\n\n#### rocky.middleware.query([ query | parserFn ])\n\nAdd/extend custom query string params to the incoming request.\n\n#### rocky.middleware.host(host)\n\nOverwrite the `Host` header before forwarding/replaying the request. Useful for some scenarios (e.g Heroku).\n\n#### rocky.middleware.reply(status, [ headers, body ])\n\nShortcut method to reply the intercepted request from the middleware, with optional `headers` and `body` data.\n\n#### rocky.middleware.redirect(url)\n\nShortcut method to redirect the current request.\n\n### rocky.Route\n\nAccessor for the [Route](https://github.com/h2non/rocky/blob/master/lib/route.js) module\n\n### rocky.Base\n\nAccessor for the [Base](https://github.com/h2non/rocky/blob/master/lib/base.js) module\n\n### rocky.protocols\n\nExpose protocol-specific [modules](https://github.com/h2non/rocky/tree/master/lib/protocols).\n\n### rocky.httpProxy\n\nAccessor for the [http-proxy](https://github.com/nodejitsu/node-http-proxy) API\n\n### rocky.MiddlewarePool\n\nMiddleware pool abstraction layer used internally by `rocky`.\nSee the [midware-pool](https://github.com/h2non/midware-pool) package for details.\n\n### rocky.VERSION\n\nCurrent rocky package semver\n\n## Special Thanks\n\n- [http-proxy](https://github.com/nodejitsu/node-http-proxy) package creators and maintainers\n- [router](https://github.com/pillarjs/router) package creators and maintainers\n\n## License\n\nMIT - Tomas Aparicio\n\n[![views](https://sourcegraph.com/api/repos/github.com/h2non/rocky/.counters/views.svg)](https://sourcegraph.com/github.com/h2non/rocky)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2non%2Frocky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh2non%2Frocky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2non%2Frocky/lists"}