HTTP Protocol

Learn about connection, redirect, caching, resource infering and dns resolution

HTTP is the main protocol Gatling targets, so that’s where we place most of our effort.

Gatling HTTP allows you to load test web applications, web services or websites. It supports HTTP and HTTPS with almost every existing feature of common browsers such as caching, cookies, redirect, etc.

However, Gatling is not a browser: it won’t run Javascript, won’t apply CSS styles and trigger CSS background-images download, won’t react to UI events, etc. Gatling works at the HTTP protocol level.

Bootstrapping

Use the http object in order to create an HTTP protocol.

As every protocol in Gatling, the HTTP protocol can be configured for a scenario. This is done thanks to the following statements:

       
HttpProtocolBuilder httpProtocol = http.baseUrl("https://gatling.io");

ScenarioBuilder scn = scenario("Scenario"); // etc...

setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol));
const httpProtocol = http.baseUrl("https://gatling.io");

const scn = scenario("Scenario"); // etc...

setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol));
val httpProtocol = http.baseUrl("https://gatling.io")

val scn = scenario("Scenario") // etc...

setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol))
val httpProtocol = http.baseUrl("https://gatling.io")

val scn = scenario("Scenario") // etc...

setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))

HTTP engine

warmUp

The Java/NIO engine start up introduces an overhead on the first request to be executed. In order to compensate this effect, Gatling automatically performs a request to https://gatling.io.

       
// change the warm up URL to https://www.google.com
http.warmUp("https://www.google.com");
// disable warm up
http.disableWarmUp();
// change the warm up URL to https://www.google.com
http.warmUp("https://www.google.com");
// disable warm up
http.disableWarmUp();
// change the warm up URL to https://www.google.com
http.warmUp("https://www.google.com")
// disable warm up
http.disableWarmUp()
// change the warm up URL to https://www.google.com
http.warmUp("https://www.google.com")
// disable warm up
http.disableWarmUp

maxConnectionsPerHost

In order to mimic real web browser, Gatling can run multiple concurrent connections per virtual user when fetching resources on the same hosts over HTTP/1.1. By default, Gatling caps the number of concurrent connections per remote host per virtual user to 6, which makes sense for modern browsers. You can change this number with maxConnectionsPerHost(max: Int).

       
http.maxConnectionsPerHost(10);
http.maxConnectionsPerHost(10);
http.maxConnectionsPerHost(10)
http.maxConnectionsPerHost(10)

shareConnections

The default behavior is that every virtual user has its own connection pool and its own SSLContext. This behavior meets your needs when you want to simulate internet traffic where each virtual user simulates a web browser.

Instead, if you want to simulate server to server traffic where the actual client has a long-lived connection pool, you want to have the virtual users share a single global connection pool.

       
http.shareConnections();
http.shareConnections();
http.shareConnections()
http.shareConnections

enableHttp2

HTTP/2 support can be enabled with the .enableHttp2 option.

       
http.enableHttp2();
http.enableHttp2();
http.enableHttp2()
http.enableHttp2

When HTTP/2 is enabled, Gatling will try to connect to your remotes using HTTP/2 through the ALPN protocol. If your remote supports HTTP/2, Gatling will use the protocol, and fall back to HTTP/1 otherwise. There is no specific code to add in the middle of your requests.

Next time you use that remote with the same user, if Gatling knows that your remote doesn’t support HTTP/2, it won’t try again and therefore won’t use ALPN.

One of the main purpose of HTTP/2 is to support multiplexing. This means that on a single connection, you are able to send multiple requests, without waiting for the responses, and receive these responses in whatever order. It means that, using HTTP/2, browsers and Gatling won’t open additional connections to the same remote for a given virtual user (assuming you don’t enable shareConnections) once they know that the remote is using HTTP/2. The first time Gatling encounters a remote, the connections will be opened like in HTTP/1 mode if there are multiple requests (for example in a resources statement). If the remote is using HTTP/1, these connections will be used if needed. If it is using HTTP/2, a single connection will be maintained, and the other ones will reach idle timeout and be closed.

You can configure which remotes support HTTP/2 or not. It means that if you are setting a remote to true (it supports HTTP/2), additional connections won’t be created the first time the remote is encountered in the simulation. If you are setting a remote to false (it doesn’t support HTTP/2), ALPN won’t be used, and additional connections will be created.

This option is useful to simulate users that already went to your website, and whose browsers already cached the fact that your website is using HTTP/2 or HTTP/1.

       
Map<String, Boolean> priorKnowledge = new HashMap<>();
priorKnowledge.put("www.google.com", true);
priorKnowledge.put("gatling.io", false);

http
  .enableHttp2()
  .http2PriorKnowledge(priorKnowledge);
const priorKnowledge = {
  "www.google.com": true,
  "gatling.io": false
};

http
  .enableHttp2()
  .http2PriorKnowledge(priorKnowledge);
http
  .enableHttp2()
  .http2PriorKnowledge(
    mapOf(
      "www.google.com" to true,
      "gatling.io" to false
    )
  )
http
  .enableHttp2
  .http2PriorKnowledge(
    Map(
      "www.google.com" -> true,
      "gatling.io" -> false
    )
  )

JDK Blocking Resolver (default)

By default, Gatling uses Java’s DNS name resolution. This cache has a TTL of 30s by default on OpenJDK and doesn’t honor the DNS records’ own TTL. You can control the TTL with:

  • the now deprecated sun.net.inetaddr.ttl System property: -Dsun.net.inetaddr.ttl=N where N is a number of seconds
  • the now recommended networkaddress.cache.ttl Security property, see reference here.

If you’re using the Java DNS name resolution and have multiple IP (multiple DNS records) for a given hostname, Gatling will automatically shuffle them to emulate DNS round-robin.

asyncNameResolution

You can use Gatling’s own async DNS resolver instead, with .asyncNameResolution().

       
// use hosts' configured DNS servers on Linux and MacOS
// use Google's DNS servers on Windows
http.asyncNameResolution();

// force DNS servers
http.asyncNameResolution("8.8.8.8");

// instead of having a global DNS resolver
// have each virtual user to have its own (hence own cache, own UDP requests)
// only effective with asyncNameResolution
http
  .asyncNameResolution()
  .perUserNameResolution();
// use hosts' configured DNS servers on Linux and MacOS
// use Google's DNS servers on Windows
http.asyncNameResolution();

// force DNS servers
http.asyncNameResolution("8.8.8.8");

// instead of having a global DNS resolver
// have each virtual user to have its own (hence own cache, own UDP requests)
// only effective with asyncNameResolution
http
  .asyncNameResolution()
  .perUserNameResolution();
// use hosts' configured DNS servers on Linux and MacOS
// use Google's DNS servers on Windows
http.asyncNameResolution()

// force DNS servers
http.asyncNameResolution("8.8.8.8")

// instead of having a global DNS resolver
// have each virtual user to have its own (hence own cache, own UDP requests)
// only effective with asyncNameResolution
http
  .asyncNameResolution()
  .perUserNameResolution()
// use hosts' configured DNS servers on Linux and MacOS
// use Google's DNS servers on Windows
http.asyncNameResolution()

// force DNS servers
http.asyncNameResolution("8.8.8.8")

// instead of having a global DNS resolver
// have each virtual user to have its own (hence own cache, own UDP requests)
// only effective with asyncNameResolution
http
  .asyncNameResolution()
  .perUserNameResolution

hostNameAliases

You can of course define hostname aliases at the OS level in the /etc/hosts file.

But you can use pass aliases programmatically.

       
http
  .hostNameAliases(Map.of("gatling.io", List.of("192.168.0.1", "192.168.0.2")));
http
  .hostNameAliases({ "gatling.io": ["192.168.0.1", "192.168.0.2"] })
http
  .hostNameAliases(mapOf("gatling.io" to listOf("192.168.0.1", "192.168.0.2")))
http
  .hostNameAliases(Map("gatling.io" -> List("192.168.0.1", "192.168.0.2")))

localAddress

It’s possible to have multiple IP addresses for your load generators, typically using IP-aliasing or iproute2.

In this case, you can bind the sockets from specific local addresses instead of the default one:

       
http.localAddress("localAddress");

http.localAddresses("localAddress1", "localAddress2");

// automatically discover all bindable local addresses
http.useAllLocalAddresses();

// automatically discover all bindable local addresses
// matching one of the Java Regex patterns
http.useAllLocalAddressesMatching("pattern1", "pattern2");
http.localAddress("localAddress");

http.localAddresses("localAddress1", "localAddress2");

// automatically discover all bindable local addresses
http.useAllLocalAddresses();

// automatically discover all bindable local addresses
// matching one of the Java Regex patterns
http.useAllLocalAddressesMatching("pattern1", "pattern2");
http.localAddress("localAddress")

http.localAddresses("localAddress1", "localAddress2")

// automatically discover all bindable local addresses
http.useAllLocalAddresses()

// automatically discover all bindable local addresses
// matching one of the Java Regex patterns
http.useAllLocalAddressesMatching("pattern1", "pattern2")
http.localAddress("localAddress")

http.localAddresses("localAddress1", "localAddress2")

// automatically discover all bindable local addresses
http.useAllLocalAddresses

// automatically discover all bindable local addresses
// matching one of the Java Regex patterns
http.useAllLocalAddressesMatching("pattern1", "pattern2")

Note that when setting multiple addresses, each virtual user is assigned to one single local address once and for all in a round-robin fashion.

perUserKeyManagerFactory

By default, Gatling uses the KeyManagerFactory configuration defined in gatling.conf, or if undefined, falls back to the JVM’s default one.

Then, it’s possible to have per virtual user KeyManagerFactories, typically if you want them to use different sets of keys.

       
http.perUserKeyManagerFactory(userId -> (javax.net.ssl.KeyManagerFactory) null);
Not supported by Gatling JS.
http.perUserKeyManagerFactory { userId -> null as KeyManagerFactory? }
http.perUserKeyManagerFactory(userId => null.asInstanceOf[javax.net.ssl.KeyManagerFactory])

This function’s input is the virtual user’s id (if you need it to generate some file’s name) and returns a javax.net.ssl.KeyManagerFactory.

Request Generation

baseUrl

As you may have seen in the previous example, you can set a base URL. This base URL will be prepended to all urls that does not start with http, e.g.:

       
HttpProtocolBuilder httpProtocol = http.baseUrl("https://gatling.io");

ScenarioBuilder scn = scenario("Scenario")
  // will make a request to "https://gatling.io/docs/"
  .exec(
    http("Relative").get("/doc/")
  )
  // will make a request to "https://github.com/gatling/gatling"
  .exec(
    http("Absolute").get("https://github.com/gatling/gatling")
  );

setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol));
const httpProtocol = http.baseUrl("https://gatling.io");

const scn = scenario("Scenario")
  // will make a request to "https://gatling.io/docs/"
  .exec(
    http("Relative").get("/doc/")
  )
  // will make a request to "https://github.com/gatling/gatling"
  .exec(
    http("Absolute").get("https://github.com/gatling/gatling")
  );

setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol));
val httpProtocol = http.baseUrl("https://gatling.io")

val scn = scenario("Scenario")
  // will make a request to "https://gatling.io/docs"
  .exec(
    http("Relative").get("/docs/")
  )
  // will make a request to "https://github.com/gatling/gatling"
  .exec(
    http("Absolute").get("https://github.com/gatling/gatling")
  )

setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol))
val httpProtocol = http.baseUrl("https://gatling.io")

val scn = scenario("Scenario")
  // will make a request to "https://gatling.io/docs/"
  .exec(
    http("Relative").get("/docs/")
  )
  // will make a request to "https://github.com/gatling/gatling"
  .exec(
    http("Absolute").get("https://github.com/gatling/gatling")
  )

setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))

baseUrls

You might want to load test several servers at the same time, to bypass a load-balancer for example.

       
http.baseUrls(
  "https://gatling.io",
  "https://github.com"
);
http.baseUrls(
  "https://gatling.io",
  "https://github.com"
);
http.baseUrls(
  "https://gatling.io",
  "https://github.com"
)
http.baseUrls(
  "https://gatling.io",
  "https://github.com"
)

Each virtual user will pick one of the baseUrls from the list once and for all when it starts, based on a round-robin strategy.

disableAutoReferer

By default, Gatling automatically computes the Referer HTTP header from the request history. You can disable this feature.

       
http.disableAutoReferer();
http.disableAutoReferer();
http.disableAutoReferer()
http.disableAutoReferer

disableCaching

By default, Gatling caches responses based on:

  • Expires header
  • Cache-Control header
  • Last-Modified header
  • ETag

You can disable this feature.

       
http.disableCaching();
http.disableCaching();
http.disableCaching()
http.disableCaching

disableUrlEncoding

Url components are supposed to be urlencoded. By default, Gatling will encode them for you.

If you know that your urls are already properly encoded and want to optimize performance, you can disable this feature.

       
http.disableUrlEncoding();
http.disableUrlEncoding();
http.disableUrlEncoding()
http.disableUrlEncoding

Note that this feature can also be disabled per request.

silentUri

Request stats are logged and then used to produce reports. Sometimes, some requests may be important for you for generating load, but you don’t actually want to report them. Typically, reporting all static resources might generate a lot of noise, and yet failed static resources might not be blocking from a user experience perspective.

Gatling provides several means to turn requests silent. Silent requests won’t be reported and won’t influence error triggers such as tryMax and exitHereIfFailed. Yet, response times will be accounted for in group times.

Some parameters are available here at protocol level, some others are available at request level.

Rules are:

  • explicitly turning a given request silent or notSilent has precedence over everything else
  • otherwise, a request is silent if it matches protocol’s silentUri filter
  • otherwise, a request is silent if it’s a resource (not a top level request) and protocol’s silentResources flag has been turned on
  • otherwise, a request is not silent
       
// make all requests whose url matches the provided Java Regex pattern silent
http.silentUri("https://myCDN/.*");
// make all resource requests silent
http.silentResources();
// make all requests whose url matches the provided Java Regex pattern silent
http.silentUri("https://myCDN/.*");
// make all resource requests silent
http.silentResources();
// make all requests whose url matches the provided Java Regex pattern silent
http.silentUri("https://myCDN/.*")
// make all resource requests silent
http.silentResources()
// make all requests whose url matches the provided pattern silent
http.silentUri("https://myCDN/.*")
// make all resource requests silent
http.silentResources

Gatling lets you define some HTTP headers to be set one all requests.

       
http
  // with a static header value
  .header("foo", "bar")
  // with a Gatling EL string header value
  .header("foo", "#{headerValue}")
  // with a function value
  .header("foo", session -> session.getString("headerValue"))
  .headers(Map.of("foo", "bar"));
http
  // with a static header value
  .header("foo", "bar")
  // with a Gatling EL string header value
  .header("foo", "#{headerValue}")
  // with a function value
  .header("foo", (session) => session.get("headerValue"))
  .headers({ "foo": "bar" });
http
  // with a static header value
  .header("foo", "bar")
  // with a Gatling EL string header value
  .header("foo", "#{headerValue}")
  // with a function value
  .header("foo") { session -> session.getString("headerValue") }
  .headers(mapOf("foo" to "bar"))
http
  // with a static header value
  .header("foo", "bar")
  // with a Gatling EL string header value
  .header("foo", "#{headerValue}")
  // with a function value
  .header("foo", session => session("headerValue").as[String])
  .headers(Map("foo" -> "bar", "baz" -> "qix"))

You have also the following built-ins for the more commons headers.

       
// all those also accept a Gatling EL string or a function parameter
http
  .acceptHeader("value")
  .acceptCharsetHeader("value")
  .acceptEncodingHeader("value")
  .acceptLanguageHeader("value")
  .authorizationHeader("value")
  .connectionHeader("value")
  .contentTypeHeader("value")
  .doNotTrackHeader("value")
  .originHeader("value")
  .userAgentHeader("value")
  .upgradeInsecureRequestsHeader("value");
// all those also accept a Gatling EL string or a function parameter
http
  .acceptHeader("value")
  .acceptCharsetHeader("value")
  .acceptEncodingHeader("value")
  .acceptLanguageHeader("value")
  .authorizationHeader("value")
  .connectionHeader("value")
  .contentTypeHeader("value")
  .doNotTrackHeader("value")
  .originHeader("value")
  .userAgentHeader("value")
  .upgradeInsecureRequestsHeader("value");
// all those also accept a Gatling EL string or a function parameter
http
  .acceptHeader("value")
  .acceptCharsetHeader("value")
  .acceptEncodingHeader("value")
  .acceptLanguageHeader("value")
  .authorizationHeader("value")
  .connectionHeader("value")
  .contentTypeHeader("value")
  .doNotTrackHeader("value")
  .originHeader("value")
  .userAgentHeader("value")
  .upgradeInsecureRequestsHeader("value")
// all those also accept a Gatling EL string or a function parameter
http
  .acceptHeader("value")
  .acceptCharsetHeader("value")
  .acceptEncodingHeader("value")
  .acceptLanguageHeader("value")
  .authorizationHeader("value")
  .connectionHeader("value")
  .contentTypeHeader("value")
  .doNotTrackHeader("value")
  .originHeader("value")
  .userAgentHeader("value")
  .upgradeInsecureRequestsHeader("value")

sign

You can set a function to sign a request once Gatling has built it, just before it’s being sent over the wire. Typically, you would compute an extra HTTP header.

       
http.sign(request -> {
  // import org.apache.commons.codec.digest.DigestUtils
  String md5 = DigestUtils.md5Hex(request.getBody().getBytes());
  request.getHeaders().add("X-MD5", md5);
  return request;
});

// or with access to the Session
http.sign((request, session) -> request);
Not supported by Gatling JS.
http.sign { request ->
  // import org.apache.commons.codec.digest.DigestUtils
  val md5 = DigestUtils.md5Hex(request.body.bytes)
  request.headers.add("X-MD5", md5)
  request
}

// or with access to the Session
http.sign { request, session -> request }
http.sign { (request, session) =>
  // import org.apache.commons.codec.digest.DigestUtils
  val md5 = DigestUtils.md5Hex(request.getBody.getBytes)
  request.getHeaders.add("X-MD5", md5)
  request
}

We also provide a built-in for OAuth1.

       
// with static values
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret"
);
// with functions
http.signWithOAuth1(
  session -> session.getString("consumerKey"),
  session -> session.getString("clientSharedSecret"),
  session -> session.getString("token"),
  session -> session.getString("tokenSecret")
);
// pass signature as form params or query params instead of an Authorization header
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret",
  false
);
// with static values
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret"
);
// with functions
http.signWithOAuth1(
  (session) => session.get("consumerKey"),
  (session) => session.get("clientSharedSecret"),
  (session) => session.get("token"),
  (session) => session.get("tokenSecret")
);
// pass signature as form params or query params instead of an Authorization header
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret",
  false
);
// with static values
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret"
)
// with functions
http.signWithOAuth1(
  { session -> session.getString("consumerKey") },
  { session -> session.getString("clientSharedSecret") },
  { session -> session.getString("token") },
  { session -> session.getString("tokenSecret") }
)
// pass signature as form params or query params instead of an Authorization header
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret",
  false
)
// parameters can also be Gatling EL strings or functions
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret"
)
// pass signature as form params or query params instead of an Authorization header
http.signWithOAuth1(
  "consumerKey",
  "clientSharedSecret",
  "token",
  "tokenSecret",
  false
)

basicAuth and digestAuth

You can set the authentication methods at protocol level to be applied to all requests.

       
// with static values
http.basicAuth("username", "password");
// with Gatling El strings
http.basicAuth("#{username}", "#{password}");
// with functions
http.basicAuth(session -> session.getString("username"), session -> session.getString("password"));

// with static values
http.digestAuth("username", "password");
// with Gatling El strings
http.digestAuth("#{username}", "#{password}");
// with functions
http.digestAuth(session -> session.getString("username"), session -> session.getString("password"));
// with static values
http.basicAuth("username", "password");
// with Gatling El strings
http.basicAuth("#{username}", "#{password}");
// with functions
http.basicAuth((session) => session.get("username"), (session) => session.get("password"));

// with static values
http.digestAuth("username", "password");
// with Gatling El strings
http.digestAuth("#{username}", "#{password}");
// with functions
http.digestAuth((session) => session.get("username"), (session) => session.get("password"));
// with static values
http.basicAuth("username", "password")
// with Gatling El strings
http.basicAuth("#{username}", "#{password}")
// with functions
http.basicAuth({ session -> session.getString("username") }) { session -> session.getString("password") }

// with static values
http.digestAuth("username", "password")
// with Gatling El strings
http.digestAuth("#{username}", "#{password}")
// with functions
http.digestAuth({ session -> session.getString("username") }) { session -> session.getString("password") }
// with static values
http.basicAuth("username", "password")
// with Gatling El strings
http.basicAuth("#{username}", "#{password}")
// with functions
http.basicAuth(session => session("username").as[String], session => session("password").as[String])

// with static values
http.digestAuth("username", "password")
// with Gatling El strings
http.digestAuth("#{username}", "#{password}")
// with functions
http.digestAuth(session => session("username").as[String], session => session("password").as[String])

Response Handling

disableFollowRedirect

By default, Gatling automatically follow redirects in case of 301, 302, 303, 307 or 308 response status code. You can disable this behavior.

       
http.disableFollowRedirect();
http.disableFollowRedirect();
http.disableFollowRedirect()
http.disableFollowRedirect

To avoid infinite redirection loops, Gatling sets a limit on the number of redirects. The default value is 20. You can tune this limit with: .maxRedirects(int)

By default, Gatling will change the method to “GET” on 302 to conform to most user agents’ behavior. You can disable this behavior and keep the original method with .strict302Handling.

redirectNamingStrategy

By default, Gatling will generate redirected request names such as “<ORIGINAL_REQUEST_NAME> Redirect <REDIRECT_COUNT>”. You can define your own custom strategy.

The function takes 3 parameters

  • uri the target Location, of type io.gatling.http.client.uri.Uri
  • originalRequestName
  • redirectCount
       
http.redirectNamingStrategy(
  (uri, originalRequestName, redirectCount) -> "redirectedRequestName"
);
Not supported by Gatling JS.
http.redirectNamingStrategy {
  uri, originalRequestName, redirectCount -> "redirectedRequestName"
}
http.redirectNamingStrategy(
  (uri, originalRequestName, redirectCount) => "redirectedRequestName"
)

transformResponse

You might want to process manually the response.

       
http.transformResponse((response, session) -> response);
Not supported by Gatling JS.
http.transformResponse { response, session -> response }
http.transformResponse((response, session) => response)

check

You can define checks at the http protocol definition level with: check(checks: HttpCheck*). They will be applied on all the requests, however you can disable them for given request thanks to the ignoreProtocolChecks method.

inferHtmlResources

Gatling can fetch resources in parallel in order to emulate the behavior of a real web browser.

At the protocol level, you can use inferHtmlResources methods, so Gatling will automatically parse HTML to find embedded resources and load them asynchronously.

The supported resources are:

  • <script>
  • <base>
  • <link> (stylesheet, icon and prefetch resources)
  • <bgsound>
  • <frame>
  • <iframe>
  • <img>
  • <input>
  • <body>
  • <applet>
  • <embed>
  • <object>
  • import directives in HTML and @import CSS rule.

Other resources are not supported: css images, javascript triggered resources, conditional comments, etc.

You can also specify AllowList and DenyList based on Java Regex patterns to have a more fine grain control on resource fetching.

       
// fetch only resources matching one of the patterns in the allow list
http.inferHtmlResources(AllowList("pattern1", "pattern2"));
// fetch all resources except those matching one of the patterns in the deny list
http.inferHtmlResources(DenyList("pattern1", "pattern2"));
// fetch only resources matching one of the patterns in the allow list
// but not matching one of the patterns in the deny list
http.inferHtmlResources(AllowList("pattern1", "pattern2"), DenyList("pattern3", "pattern4"));
// fetch only resources matching one of the patterns in the allow list
http.inferHtmlResources(AllowList("pattern1", "pattern2"));
// fetch all resources except those matching one of the patterns in the deny list
http.inferHtmlResources(DenyList("pattern1", "pattern2"));
// fetch only resources matching one of the patterns in the allow list
// but not matching one of the patterns in the deny list
http.inferHtmlResources(AllowList("pattern1", "pattern2"), DenyList("pattern3", "pattern4"));
// fetch only resources matching one of the patterns in the allow list
http.inferHtmlResources(AllowList("pattern1", "pattern2"))
// fetch all resources except those matching one of the patterns in the deny list
http.inferHtmlResources(DenyList("pattern1", "pattern2"))
// fetch only resources matching one of the patterns in the allow list
// but not matching one of the patterns in the deny list
http.inferHtmlResources(AllowList("pattern1", "pattern2"), DenyList("pattern3", "pattern4"))
// fetch only resources matching one of the patterns in the allow list
http.inferHtmlResources(AllowList("pattern1", "pattern2"))
// fetch all resources except those matching one of the patterns in the deny list
http.inferHtmlResources(DenyList("pattern1", "pattern2"))
// fetch only resources matching one of the patterns in the allow list
// but not matching one of the patterns in the deny list
http.inferHtmlResources(AllowList("pattern1", "pattern2"), DenyList("pattern3", "pattern4"))

nameInferredHtmlResources

By default, Gatling will generate resource request names automatically. You can control this behavior and even define your own custom strategy.

       
// (default): name requests after the resource's url tail (after last `/`)
http.nameInferredHtmlResourcesAfterUrlTail();
// name requests after the resource's path
http.nameInferredHtmlResourcesAfterPath();
// name requests after the resource's absolute url
http.nameInferredHtmlResourcesAfterAbsoluteUrl();
// name requests after the resource's relative url
http.nameInferredHtmlResourcesAfterRelativeUrl();
// name requests after the resource's last path element
http.nameInferredHtmlResourcesAfterLastPathElement();
// name requests with a custom strategy
http.nameInferredHtmlResources(uri -> "name");
// (default): name requests after the resource's url tail (after last `/`)
http.nameInferredHtmlResourcesAfterUrlTail();
// name requests after the resource's path
http.nameInferredHtmlResourcesAfterPath();
// name requests after the resource's absolute url
http.nameInferredHtmlResourcesAfterAbsoluteUrl();
// name requests after the resource's relative url
http.nameInferredHtmlResourcesAfterRelativeUrl();
// name requests after the resource's last path element
http.nameInferredHtmlResourcesAfterLastPathElement();
// (default): name requests after the resource's url tail (after last `/`)
http.nameInferredHtmlResourcesAfterUrlTail()
// name requests after the resource's path
http.nameInferredHtmlResourcesAfterPath()
// name requests after the resource's absolute url
http.nameInferredHtmlResourcesAfterAbsoluteUrl()
// name requests after the resource's relative url
http.nameInferredHtmlResourcesAfterRelativeUrl()
// name requests after the resource's last path element
http.nameInferredHtmlResourcesAfterLastPathElement()
// name requests with a custom strategy
http.nameInferredHtmlResources { uri -> "name" }
// (default): name requests after the resource's url tail (after last `/`)
http.nameInferredHtmlResourcesAfterUrlTail
// name requests after the resource's path
http.nameInferredHtmlResourcesAfterPath
// name requests after the resource's absolute url
http.nameInferredHtmlResourcesAfterAbsoluteUrl
// name requests after the resource's relative url
http.nameInferredHtmlResourcesAfterRelativeUrl
// name requests after the resource's last path element
http.nameInferredHtmlResourcesAfterLastPathElement
// name requests with a custom strategy
http.nameInferredHtmlResources(uri => "name")

Proxy

You can tell Gatling to use a proxy to send the HTTP requests. You can optionally set a different port for HTTPS and credentials:

       
// clear HTTP proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .http()
    // optional
    .credentials("myUsername", "myPassword")
);

// HTTPS proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .https()
);

// SOCKS4 proxy
http.proxy(
  Proxy("mySocks4ProxyHost", 8080)
    .socks4()
);

// SOCKS5 proxy
http.proxy(
  Proxy("mySocks5ProxyHost", 8080)
    .socks5()
);
// clear HTTP proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .http()
    // optional
    .credentials("myUsername", "myPassword")
);

// HTTPS proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .https()
);

// SOCKS4 proxy
http.proxy(
  Proxy("mySocks4ProxyHost", 8080)
    .socks4()
);

// SOCKS5 proxy
http.proxy(
  Proxy("mySocks5ProxyHost", 8080)
    .socks5()
);
// clear HTTP proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    // optional
    .credentials("myUsername", "myPassword")
)

// HTTPS proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .https()
)

// SOCKS4 proxy
http.proxy(
  Proxy("mySocks4ProxyHost", 8080)
    .socks4()
)

// SOCKS5 proxy
http.proxy(
  Proxy("mySocks5ProxyHost", 8080)
    .socks5()
)
// clear HTTP proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .credentials("myUsername", "myPassword")
)

// HTTPS proxy
http.proxy(
  Proxy("myHttpProxyHost", 8080)
    .https
)

// SOCKS4 proxy
http.proxy(
  Proxy("mySocks4ProxyHost", 8080)
    .socks4
)

// SOCKS5 proxy
http.proxy(
  Proxy("mySocks5ProxyHost", 8080)
    .socks5
)

You can also disable the use of proxy for some hosts with noProxyFor:

       
http
  .proxy(Proxy("myProxyHost", 8080))
  .noProxyFor("www.github.com", "gatling.io");
http
  .proxy(Proxy("myProxyHost", 8080))
  .noProxyFor("www.github.com", "gatling.io");
http
  .proxy(Proxy("myProxyHost", 8080))
  .noProxyFor("www.github.com", "gatling.io")
http
  .proxy(Proxy("myProxyHost", 8080))
  .noProxyFor("www.github.com", "gatling.io")

Finally, you can use proxyProtocolSourceIpV4Address and proxyProtocolSourceIpV6Address to generate fake PROXY protocol headers.

       
http
    // use a Gatling EL to pass the IPV4 local address
    // to be used to generate a PROXY protocol header
    // when the connection uses IPv4
    .proxyProtocolSourceIpV4Address("#{myIpV4AddressString}")
    // use a function instead,
    // but it will be resolved on each request execution
    .proxyProtocolSourceIpV4Address(session -> "199.60.103.60")
    // use a Gatling EL to pass the IPV6 local address
    // to be used to generate a PROXY protocol header
    // when the connection uses IPv6
    .proxyProtocolSourceIpV6Address("#{myIpV6AddressString}")
    // use a function instead,
    // but it will be resolved on each request execution
    .proxyProtocolSourceIpV6Address(session -> "2a00:1450:4007:810::200e");
http
  // use a Gatling EL to pass the IPV4 local address
  // to be used to generate a PROXY protocol header
  // when the connection uses IPv4
  .proxyProtocolSourceIpV4Address("#{myIpV4AddressString}")
  // use a function instead,
  // but it will be resolved on each request execution
  .proxyProtocolSourceIpV4Address((session) => "199.60.103.60")
  // use a Gatling EL to pass the IPV6 local address
  // to be used to generate a PROXY protocol header
  // when the connection uses IPv6
  .proxyProtocolSourceIpV6Address("#{myIpV6AddressString}")
  // use a function instead,
  // but it will be resolved on each request execution
  .proxyProtocolSourceIpV6Address((session) => "2a00:1450:4007:810::200e")
http
  // use a Gatling EL to pass the IPV4 local address
  // to be used to generate a PROXY protocol header
  // when the connection uses IPv4
  .proxyProtocolSourceIpV4Address("#{myIpV4AddressString}")
  // use a function instead,
  // but it will be resolved on each request execution
  .proxyProtocolSourceIpV4Address { session -> "199.60.103.60" }
// use a Gatling EL to pass the IPV6 local address
// to be used to generate a PROXY protocol header
// when the connection uses IPv6
.proxyProtocolSourceIpV6Address("#{myIpV6AddressString}")
  // use a function instead,
  // but it will be resolved on each request execution
  .proxyProtocolSourceIpV6Address { session -> "2a00:1450:4007:810::200e" }
http
  // use a Gatling EL to pass the IPV4 local address
  // to be used to generate a PROXY protocol header
  // when the connection uses IPv4
  .proxyProtocolSourceIpV4Address("#{myIpV4AddressString}")
  // use a function instead,
  // but it will be resolved on each request execution
  .proxyProtocolSourceIpV4Address(session => "199.60.103.60")
  // use a Gatling EL to pass the IPV6 local address
  // to be used to generate a PROXY protocol header
  // when the connection uses IPv6
  .proxyProtocolSourceIpV6Address("#{myIpV6AddressString}")
  // use a function instead,
  // but it will be resolved on each request execution
  .proxyProtocolSourceIpV6Address(session => "2a00:1450:4007:810::200e")

Edit this page on GitHub