Skip to content

Modifier Reference

Adam Tanner edited this page Aug 27, 2015 · 13 revisions

Martian uses the term Modifier to refer to any struct that implements the Modifier interface and that can be registered into the parsing system. Think of a Modifier as anything that has access to the request or response before (or after) the HTTP round trip (regardless of whether or not the request or response is actually mutated).

Modifiers

Modifiers are able to mutate a request, a response or both.

Logging

The log.Logger logs requests and responses to stdout. The logger may be used in combination with filters, groups, etc. for finer logging control. The body of requests and responses are logged by default, optionally decompressing and dechunking them if decode is set to true.

This may impact performance as the entire message body must be loaded into memory. For cases where this performance impact may be prohibitive (streaming video) the headersOnly key may be used to skip logging the body.

Example configuration for logging requests and responses with decoded message bodies:

{
  "log.Logger": {
    "scope": ["request", "response"],
    "decode": true
  }
}

Cookie

The cookie.Modifier injects a cookie into a request or a response.

Example configuration that injects a Martian-Cookie cookie into responses:

{
  "cookie.Modifier": {
    "scope": ["response"],
    "name": "Martian-Cookie",
    "value": "some value",
    "path": "/some/path",
    "domain": "example.com",
    "expires": "2025-04-12T23:20:50.52Z", // RFC 3339
    "secure": true,
    "httpOnly": false,
    "maxAge": 86400
  }
}

Header

The header.Modifier injects or modifies headers in a request or a response.

Example configuration that injects an X-Martian header with the value of true into requests:

{
  "header.Modifier": {
    "scope": ["request"],
    "name": "X-Martian",
    "value": "true"
  }
}

Header Blacklist

The header.Blacklist deletes headers from a request or a response.

Example configuration that deletes response headers with the names X-Martian and Y-Martian:

{
  "header.Blacklist": {
    "scope": ["response"],
    "names": ["X-Martian", "Y-Martian"]
  }
}

Query String

The querystring.Modifier adds or modifies query string parameters on a request. Any existing parameter values are replaced.

Example configuration that sets the query string parameter foo to the value of bar on requests and responses:

{
  "querystring.Modifier": {
    "scope": ["request", "response"],
    "name": "foo",
    "value": "bar"
  }
}

Status

The status.Modifier modifies the HTTP status code on a response.

Example configuration that sets the HTTP status of responses to 200:

{
  "status.Modifier": {
    "scope": ["response"],
    "statusCode": 200
  }
}

URL

The url.Modifier modifies the URL on a request.

Example configuration that redirects requests to https://www.google.com/proxy?testing=true

{
  "url.Modifier": {
    "scope": ["request"],
    "scheme": "https",
    "host": "www.google.com",
    "path": "/proxy",
    "query": "testing=true"
  }
}

Message Body

The body.Modifier modifies the body of a request or response. Additionally, it will modify the following headers to ensure proper transport: Content-Type, Content-Length, Content-Encoding. The body is expected to be uncompressed and Base64 encoded.

{
  "body.Modifier": {
    "scope": ["request", "response"],
    "contentType": "text/plain; charset=utf-8",
    "body": "TWFydGlhbiBpcyBhd2Vzb21lIQ=="
  }
}

Groups

Groups hold lists of modifiers (or filters, or groups) that are executed in a particular order.

FIFO

A fifo.Group holds a list of modifiers that are executed in first-in, first-out order.

Example configuration that adds the query string parameter of foo=bar on the request and deletes any X-Martian headers on responses:

{
  "fifo.Group": {
    "scope": ["request", "response"],
    "modifiers": [
      {
        "querystring.Modifier": {
          "scope": ["request"],
          "name": "foo",
          "value": "bar"
        }
      },
      {
        "header.Blacklist": {
          "scope": ["response"],
          "names": ["X-Martian"]
        }
      }
    ]
  }
}

Priority

A priority.Group holds a list of modifiers that are each associated with an integer. Each integer represents the "priority" of the associated modifier, and the modifiers are run in order of priority (from highest to lowest).

In the case that two modifiers have the same priority, order of execution of those modifiers will be determined by the order in which the modifiers with the same priority were added: the newest modifier added will run first.

Example configuration that adds the query string parameter of foo=bar and deletes any X-Martian headers on requests:

{
  "priority.Group": {
    "scope": ["response"],
    "modifiers": [
      {
        "priority": 0 // will run last
        "modifier" : {
          "querystring.Modifier": {
            "scope": ["response"],
            "name": "foo",
            "value": "bar"
          }
        }
      },
      {
        "priority" : 100 // will run first
        "modifier" : {
          "header.Blacklist": {
            "scope": ["response"],
            "names": ["X-Martian"]
          }
        }
      }
    ]
  }
}

Filters

Filters execute contained modifiers if the defined conditional is met.

Header

The header.Filter executes its contained modifier if the a request or response contains a header that matches the defined name and value. In the case that the value is undefined, the contained modifier executes if a request or response contains a header with the defined name.

Example configuration that add the query string parameter foo=bar on responses if the response contains a Martian-Testing header with the value of true:

{
  "header.Filter": {
    "scope": ["response"],
    "name": "Martian-Testing",
    "value": "true",
    "modifier": {
      "querystring.Modifier": {
        "scope": ["response"],
        "name": "foo",
        "value": "bar"
      }
    }
  }
}

Query String

The querystring.Filter executes its contained modifier if the request or response contains a query string parameter matches the defined name and value in the filter. The name and value in the filter are regular expressions in the RE2 syntax. In the case that a value is not defined, the contained modifier is executed if the query string parameter name matches.

Example of a configuration that sets the Mod-Run header to true on requests with the query string parameter to param=true:

{
  "querystring.Filter": {
    "scope": ["request"],
    "name": "param",
    "value": "true",
    "modifier": {
      "header.Modifier": {
        "scope": ["request"],
        "name": "Mod-Run",
        "value": "true"
      }
    }
  }
}

URL

The url.Filter executes its contained modifier if the request URL matches all of the provided parts. Missing parameters are ignored.

Example configuration that sets the Mod-Run header to true on all requests that are made to a URL with the scheme https.

{
  "url.Filter": {
    "scope": ["request"],
    "scheme": "https",
    "modifier": {
      "header.Modifier": {
        "scope": ["request"],
        "name": "Mod-Run",
        "value": "true"
      }
    }
  }
}

Verifiers

Verifier check network traffic against defined expectations. Failed verifications are returned as a list of errors.

Header

The header.Verifier records an error for every request or response that does not contain a header that matches the name and value. In the case that a value is not provided, the an error is recorded for every failed match of the name.

Example configuration that records an error if the Martian-Test header is not set to true on requests and responses:

{
  "header.Verifier": {
    "scope": ["request", "response"],
    "name": "Martian-Test",
    "value": "true"
  }
}

Method

The method.Verifier records an error for every request that does not match the expected HTTP method.

Example configuration that records an error for every request that is not a POST:

{
  "method.Verifier": {
    "scope": ["request"],
    "method": "POST"
  }
}

Pingback

The pingback.Verifier records an error for every request that fails to generate a pingback request with the provided url parameters. In the case that certain parameters are not provided, those portions of the URL are not used for matching.

Example configuration that records an error for every request that does not result in a pingback to https://example.com/testing?test=true:

{
  "pingback.Verifier": {
    "scope": ["request"],
    "scheme": "https",
    "host": "example.com",
    "path": "/testing",
    "query": "test=true"
  }
}

Query String

The querystring.Verifier records an error for every request or response that does not contain a query string parameter that matches the name and value. In the case that a value is not provided, then an error is recorded of every failed match of name, ignoring any value.

Example configuration that records an error for each request that does not contain a query string parameter of param=true:

{
  "querystring.Verifier": {
    "scope": ["request"],
    "name": "param",
    "value": "true"
  }
}

Status

The status.Verifier records an error for every response that is returned with a HTTP status that does not match the statusCode provided.

Example configuration that records an error for each response that does not have the HTTP status of 200 OK:

{
  "status.Verifier": {
    "scope": ["response"],
    "statusCode": 200
  }
}

URL

The url.Verifier records an error for every request URL that does not match all provided parts of a URL.

Example configuration that records an error for each request that is not for https://www.martian.proxy/testing?test=true:

{
  "url.Verifier": {
    "scope": ["request"],
    "scheme": "https",
    "host": "www.martian.proxy",
    "path": "/testing",
    "query": "test=true"
  }
}