Configuring wiretap

How to configure wiretap for your project.

Using flags

The following flags exist for configuring wiretap:

Flag Short Code Description
–url -u Set the redirect URL for wiretap to send traffic to [required]
–port -p Set port on which to listen for HTTP traffic (default is 9090)
–monitor-port -m Set port on which to serve the monitor UI (default is 9091)
–ws-port -w Set port on which to serve the monitor UI websocket (default is 9092)
–spec -s Set the path to the OpenAPI specification to use
–static -t Set the path to a directory of static files to serve
–static-index -i Set the index filename for static file serving (default is index.html)
–delay -d Set a global delay for all API request responses
–config -c Location of a wiretap configuration file (default is wiretap.yaml)
–cert -n Location of a certificate file to enable TLS/HTTPS and HTTP/2
–key -k Location of a certificate private key to enable TLS/HTTPS and HTTP/2
–mock-mode -x Enable mock mode, all responses will be generated according to the OpenAPI spec (requires -u)
–hard-validation -e Return an HTTP error code for non-compliant request/response (default is false)
–hard-validation-code -q Return set the HTTP error code for failed requests with hard-validation (default code is 400)
–hard-validation-return-code -y Return set the HTTP error code for failed responses with hard-validation (default code is 502)
–har -z Load a HAR file instead of sniffing traffic
–har-validate -g Load a HAR file instead of sniffing traffic, and validate against OpenAPI specification (requires -s) (headless mode)
–har-allow -g Add a path to the HAR allow list, can use arg multiple times
–report-filename -g Filename for any headless report generation output
–stream-report -a Stream violations to report JSON file as they occur (headless mode)

There are multiple elements that cannot be configured via flags:

  • Path rewriting rules
  • Path delay rules
  • Header injection/dropping rules
  • Static file path catch-all rules
  • Variables
  • Basic authorization credentials
  • Ignoring and allowing redirects

Using a configuration file

wiretap will automatically look for a file named wiretap.yaml in the current working directory. Then wiretap will look for a file named wiretap.yaml in the user’s home directory.

To use a custom location for the config file, use the -c or --config flag.

The above list can only be configured via a config file. All the flag options can be also configured via a config file.

Here’s an example config file that sets all the above flags to a value other than default.

redirectURL: http://some.api-host-outhere.some-domain.com
port: 5728
monitorPort: 5729
webSocketPort: 5730
contract: ./some-openapi-spec.yaml
staticDir: ./some-static-files
staticIndex: index.html
globalAPIDelay: 1000
certificate: config/sample_cert.crt
certificateKey: config/sample_key.pem
hardValidation: true
hardValidationCode: 422
hardValidationReturnCode: 500
mockMode: true

Available configuration properties

Property Type Description
redirectURL string Set the redirect URL for wiretap to send traffic to [required]
port int Set port on which to listen for HTTP traffic (default is 9090)
monitorPort int Set port on which to serve the monitor UI (default is 9091)
webSocketPort int Set port on which to serve the monitor UI websocket (default is 9092)
contract string Set the path to the OpenAPI specification to use
staticDir string Set the path to a directory of static files to serve
staticIndex string Set the index filename for static file serving (default is index.html)
globalAPIDelay -d Set a global delay for all API request responses
variables map[key]value Set variables as key/value map
staticPaths []string Set paths to act as ‘catch-all’ paths to load index (for SPA’s)
paths []PathConfig Configure paths for different kinds of mutation (see path configurations)
pathDelays map[string]int Configure different delays for different paths (see path delay configurations)
certificate string Set the path to a valid certificate, this will enable TLS/HTTPS and HTTP/2 (see enabling TLS/HTTPS)
certificateKey string Set the path to a valid certificate private key, this will enable TLS/HTTPS and HTTP/2 (see enabling TLS/HTTPS)
hardValidation boolean Enable hard validation mode, validation failure returns an HTTP error code (see hard validation mode)
hardValidationCode int Set the HTTP error code for failed requests when using hardValidation. (default is 400)
hardValidationReturnCode int Set the HTTP error code for failed responses when using hardValidation. (default is 502)
mockMode boolean Enable mock mode, All responses are mocked acording to the OpenAPI spec (default is 502)
streamMode boolean Stream violations to a JSON report file as they occur (headless mode)
har string Load a HAR file into memory
harValidate boolean Validate HAR file instead of reviewing it through monitor UI
harAllowList []string Array of base paths to validate against
ignoreRedirects []string Array of paths glob patterns to ignore HTTP redirects on (see redirect configurations)
allowRedirects []string Array of paths glob patterns to allow HTTP redirects on (see redirect configurations)

Variables

Variables can be used to replace values across path configurations, to make it easier to change values in one place, vs having to copy/paste values across multiple places, and it makes it easier to automate the configuration of wiretap.

The variables section of the config file is a simple key/value map of variables to values.

To use a variable in a path configuration, wrap the variable name in a dollar symbol with braces, like this: ${myVariableName}.

This syntax is the same used by JavaScript templating engines.

variables:
  myVariableName: my-variable-value
  somethingElse: 1234

Path configuration

Paths can be individually configured to rewrite sections of that path, inject or drop headers, use basic authentication and set a unique target for each path configuration.

To configure paths we need to create a paths section in our config file.

This configuration format was lifted directly from http-proxy-middleware.

A path configuration can also support a header configuration (see more below)

Path rewriting

When developing an application locally, paths often need to be re-written to allow local API calls to be re-routed to another live endpoint, so that applications can be testing against live data.

These paths can be complex and strange and often need to be rewritten in a specific way.

To configure a path rewrite, we need to specify the path to match on, the target to rewrite to, and optionally a pathRewrite section to further rewrite the path.

For example, this rule will match all paths that match the following glob pattern: /en-US/pb33f/__raw/* and rewrite and paths that match the following regex pattern: /en-US/pb33f/__raw/(\w+)/nobody/ to $1/-/.

So the path /en-US/pb33f/__raw/123abc/nobody/ will be rewritten to https://localhost:80/123abc/-/ when making the API call under the covers.

paths:
  /en-US/pb33f/__raw/*:
    target: localhost:80
    secure: true
    pathRewrite:
      '^/en-US/pb33f/__raw/(\w+)/nobody/': '$1/-/'

When using pathRewrite, these are regular expressions, so we can use capture groups to capture parts of the path by using dollar prefixed numbers ($1, $2, etc).

Path delay configuration

The globalAPIDelay configuration property can be used to set a global delay for all API requests, but sometimes we need to set different delays for different paths. We need finer grain control over the delay.

To configure path delays we need to create a pathDelays section in our config file.

This section takes a map of path glob patterns to delay values in milliseconds.

pathDelays:
  "/very/slow/path/*": 7000
  "/not/so/slow/*/path": 2000
  "/faster/path": 300

Basic authentication

To apply basic authentication to a path, we can use the auth section. This section takes a string in the format of username:password and will apply the Authorization header to the request.

The username and password support variables, and the entire string is base64 encoded, when being auto-injected as a header.

paths:
  /some/auth:
    target: ${someHost}/some/auth
    secure: true
    auth: "${someUser}:${somePass}"

Ignoring and allowing redirects

To ignore or allow redirects on specific paths, we can use the ignoreRedirects and allowRedirects sections. These sections take an array of glob patterns to match on.

By default wiretap will follow all redirects, but if we want to ignore or allow redirects on specific paths, we can use these.

ignoreRedirects:
  - /en-US/pb33f/__raw/*
  - /some/auth
allowRedirects:
  - /bouncy/path/*

This usecase exists because some APIs are poorly architected and tend to stuff requests full of cookies and then bounce around multiple redirects before finally landing on the correct endpoint.

If you have ever used corporate authentication systems, you’ll know what we’re talking about.


Configuring path headers

Each path configuration can also support a header configuration (see more below).


Headers

When developing an application locally, headers often need to be dropped or injected to allow local API calls to be parsed correctly by the target API.

To configure path headers we need to create a headers section in our config file for global headers, or we can also create a headers section under a specific path configuration.

Dropping headers

To drop specific output requests, we can use the drop section. This section takes an array of header names to drop.

Header values support variables as well.

headers:
  drop:
    - Origin
    - X-Some-Header

Injecting headers

To inject specific headers for each request we can use the inject section. This section takes a key/value map of header names to values.

The values support variables as well.

headers:
  inject:
    X-My-Header: ${someVar}
    Authorization: Bearer ${someToken}

Static paths

If our application is a Single Page Application (SPA), we’re going to need to serve static files from our application, and potentially configure a catch-all rule to serve the index.html file for all paths that don’t come off the index or root of the application. (/)

To configure static path catch-all rules we need to create a staticPaths section in our config file.

This section takes an array of glob patterns to match on. All matching paths will be routed to the value set by the static-index flag or staticIndex config value.

staticPaths:
  - /en-US/app/* 
  - /some-other-app-path/*/something/*

Enabling TLS/HTTP2

A certificate and certificate private key can be provided to enable TLS/HTTPS and HTTP/2. Use the flags --cert and --key to set the location of the certificate and certificate private key respectively.

wiretap --cert ./config/sample_cert.crt --key ./config/sample_key.pem ...

The same settings can be applied via the config file.

certificate: config/sample_cert.crt
certificateKey: config/sample_key.pem

Everything will now run over TLS/HTTPS and HTTP/2. All the ports are the same, but the http scheme will be https:// instead of http://.

Hard validation mode

wiretap can be configured to override the return code for non-compliant requests and responses. Any request or response that does not match the OpenAPI specification will return an HTTP error code.

Enabling this mode can work wonders for a CI/CD pipeline and integration tests, where you want to fail a build if the API is not compliant with an OpenAPI contract.

To enable hard validation mode, use the --hard-validation / -q flag.

wiretap --hard-validation ...

Or use the hardValidation config property and set the value to true

certificate: config/sample_cert.crt
hardValidation: true

The default HTTP error code for failed requests is 400, but this can be configured via the --hard-validation-code / -q flag.

wiretap --hard-validation --hard-validation-code 422 ...

The default HTTP error code for failed requests is 502, but this can be configured via the --hard-validation-return-code / -y flag.

wiretap --hard-validation --hard-validation-return-code 500 ...

Mock mode

wiretap can be configured to return mocked responses for all requests. This is useful for testing and development, when you don’t want to make real API calls, but you want to test your application against a real API.

Mock mode is a true test of your OpenAPI contract, because it will generate responses based on the contract.

To enable mock mode, use the --mock-mode / -x flag.

wiretap -x ...

Example config file

Here is an example of a wiretap configuration file that sets all available values.

variables:
  someVar: some-value
  someUser: some-user
  somePass: some-pass
  someToken: aabbcc1234
  someHost: some.api-host-outhere.some-domain.com
redirectURL: http://my.api-host-outhere.some.domain
port: 9090
monitorPort: 9091
webSocketPort: 9092
contract: ./some-openapi-spec.yaml
staticDir: ./some-static-files
staticIndex: index.html
globalAPIDelay: 1000
headers:
  drop:
    - Origin
    - X-Some-Header
staticPaths:
  - /en-US/app/*
  - /some-other-app-path/*/something/*
paths:
  /en-US/pb33f/__raw/*:
    target: ${someHost}:8080
    secure: true
    pathRewrite:
      '^/en-US/pb33f/__raw/(\w+)/nobody/': '$1/-/'
    headers:
      inject:
        X-My-Header: ${someVar}
        Authorization: Bearer ${someToken}
      drop:
        - X-Some-Header
  /basic/auth:
    target: ${someHost}/some/auth
    secure: true
    auth: "${someUser}:${somePass}"
certificate: config/sample_cert.crt
certificateKey: config/sample_key.pem
hardValidation: true
hardValidationCode: 422
hardValidationReturnCode: 500
pathDelays:
  "/very/slow/path/*": 7000
  "/not/so/slow/*/path": 2000
  "/faster/path": 300
ignoreRedirects:
  - /en-US/pb33f/__raw/*
  - /some/auth
allowRedirects:
  - /bouncy/path/*