Gatling’s HTTP protocol configuration is a DSL that lets you define the behavior of your simulated HTTP clients, and it’s far more powerful than just setting a base URL.
Let’s see it in action. Imagine we want to test an API that requires a X-Tenant-ID header and a Bearer token for authentication. Here’s how you’d set that up in Gatling:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
object ApiScenario {
val httpProtocol = http
.baseUrl("https://api.example.com")
.acceptHeader("application/json")
.contentTypeHeader("application/json")
.header("X-Tenant-ID", "my-test-tenant") // Custom header
.authorizationHeader("Bearer YOUR_ACCESS_TOKEN") // Authentication header
val scn = scenario("API Load Test")
.exec(http("Get Users")
.get("/users")
.check(status.is(200))
)
.pause(1 second)
.exec(http("Create User")
.post("/users")
.body(StringBody("""{"name": "Test User", "email": "test@example.com"}"""))
.check(status.is(201))
)
val setUp =
setUp(
scn.inject(rampUsers(100) during (30 seconds))
).protocols(httpProtocol)
}
This httpProtocol block is where you define the common settings for all HTTP requests in your simulation. It’s not just about the base URL; you’re setting up default headers, connection pooling, and even specifying how Gatling should handle redirects or timeouts.
The baseUrl is straightforward, but notice acceptHeader and contentTypeHeader. These set the Accept and Content-Type headers for all requests unless overridden at the individual request level. This is a huge time-saver.
The real power comes with custom headers like header("X-Tenant-ID", "my-test-tenant") and authorizationHeader("Bearer YOUR_ACCESS_TOKEN"). These are injected into every request originating from this protocol configuration. This is crucial for APIs that require specific authentication schemes or tenant isolation.
The authorizationHeader is a common shortcut for header("Authorization", ...). Gatling provides these convenience methods for frequently used headers.
Internally, Gatling uses an HttpClient (from the Netty project) under the hood. When you define an httpProtocol, Gatling configures this underlying client. This includes setting up connection pools, SSL contexts, and other network-level details. By default, Gatling is quite efficient, reusing connections and managing them intelligently.
You can also configure more advanced settings within httpProtocol. For example, to disable automatic redirects:
val httpProtocol = http
.baseUrl("https://api.example.com")
.disableCaching() // Prevents caching of responses
.doNotTrack() // Sets the Do-Not-Track header
.inferHtmlResources() // Tries to infer resources from HTML responses
.noFollowRedirects() // Explicitly disable redirects
Or to set specific timeouts:
val httpProtocol = http
.baseUrl("https://api.example.com")
.connectTimeout(5000 milliseconds) // Max time to establish connection
.requestTimeout(10000 milliseconds) // Max time to receive response
These settings allow you to precisely mimic the behavior of real clients, including their potential issues with slow networks or misbehaving servers.
When you define multiple httpProtocol configurations, you can then assign them to specific scenarios using setUp(scenario.inject(...).protocols(protocol1, protocol2)). This is useful if you’re testing different API endpoints that might have distinct requirements, like one using basic auth and another using OAuth.
What most people don’t realize is that Gatling’s httpProtocol can also define warmUp strategies for connections. Before your actual scenario starts injecting users, you can configure Gatling to establish a certain number of connections and even send a few initial requests. This helps to ensure that your load test doesn’t get skewed by initial connection establishment delays. You’d add this to your setUp block like so:
setUp(
scn.inject(rampUsers(100) during (30 seconds))
).protocols(httpProtocol).warmUp(url("https://api.example.com/health")).users(10)
This pre-establishes connections and sends 10 requests to the /health endpoint before the main ramp-up begins, ensuring your load test starts with established connections.
The next step in mastering Gatling’s HTTP capabilities is often understanding how to handle dynamic data, such as session tokens that change with each request or response.