HTTP Request
How to craft HTTP requests, including HTTP method like GET or POST, HTTP headers, query parameters, form parameters, body and checks.
Request Name
HTTP support has a dedicated DSL, whose entry point is the http(requestName)
method.
This request name is important because it will act as a key when computing stats for the reports. If the same name appears in multiple places in a Simulation, Gatling will consider those requests are of the same type and their statistics will be aggregated.
// with a static value
http("requestName").get("https://gatling.io");
// with a static value
http("#{requestName}").get("https://gatling.io");
// with a static value
http(session -> session.getString("requestName")).get("https://gatling.io");
// with a static value
http("requestName").get("https://gatling.io")
// with a static value
http("#{requestName}").get("https://gatling.io")
// with a static value
http { session -> session.getString("requestName") }.get("https://gatling.io")
// with a static value
http("requestName").get("https://gatling.io")
// with a static value
http("#{requestName}").get("https://gatling.io")
// with a static value
http(session => session("requestName").as[String]).get("https://gatling.io")
HTTP requests have to be passed to the exec()
method in order to be attached to the scenario and be executed.
// inline style
scenario("scenarioName")
.exec(http("requestName").get("url"));
// non inline style
HttpRequestActionBuilder request = http("RequestName").get("url");
scenario("MyScenario")
.exec(request);
// inline style
scenario("scenarioName")
.exec(http("requestName").get("url"))
// non inline style
val request = http("RequestName").get("url")
scenario("MyScenario")
.exec(request)
// inline style
scenario("ScenarioName")
.exec(http("RequestName").get("url"))
// non inline style
val request = http("RequestName").get("url")
scenario("ScenarioName")
.exec(request)
Method and URL
Gatling provides built-ins for the most common methods. Those are simply the method name in minor case.
// with an absolute static url
http("name").get("https://gatling.io");
// with an absolute static url
http("name").get("#{url}");
// with an absolute static url
http("name").get(session -> session.getString("url"));
http("name").put("https://gatling.io");
http("name").post("https://gatling.io");
http("name").delete("https://gatling.io");
http("name").head("https://gatling.io");
http("name").patch("https://gatling.io");
http("name").options("https://gatling.io");
http("name").httpRequest("PURGE", "http://myNginx.com");
// with an absolute static url
http("name").get("https://gatling.io")
// with an absolute static url
http("name").get("#{url}")
// with an absolute static url
http("name").get { session -> session.getString("url") }
http("name").put("https://gatling.io")
http("name").post("https://gatling.io")
http("name").delete("https://gatling.io")
http("name").head("https://gatling.io")
http("name").patch("https://gatling.io")
http("name").options("https://gatling.io")
http("name").httpRequest("PURGE", "http://myNginx.com")
// with an absolute static url
http("name").get("https://gatling.io")
// with an absolute static url
http("name").get("#{url}")
// with an absolute static url
http("name").get(session => session("url").as[String])
http("name").put("https://gatling.io")
http("name").post("https://gatling.io")
http("name").delete("https://gatling.io")
http("name").head("https://gatling.io")
http("name").patch("https://gatling.io")
http("name").options("https://gatling.io")
http("name").httpRequest("PURGE", "http://myNginx.com")
Query Parameters
Frameworks and developers often pass additional information in the query, which is the part of the url after the ?
. A query is composed of key=value pairs, separated by &
. Those are named query parameters.
For example, https://github.com/gatling/gatling/issues?milestone=1&state=open
contains 2 query parameters:
milestone=1
: the key is milestone and its value is 1state=open
: the key is state and its value is open
In order to set the query parameters of an HTTP request, you can:
- either pass the full query in the url, e.g.:
http("Issues")
.get("https://github.com/gatling/gatling/issues?milestone=1&state=open");
http("Issues")
.get("https://github.com/gatling/gatling/issues?milestone=1&state=open")
http("Issues")
.get("https://github.com/gatling/gatling/issues?milestone=1&state=open")
- or pass query parameters one by one to the method named
queryParam
:
// with static values
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "1")
.queryParam("state", "open");
// with Gatling EL strings
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "#{milestoneValue}")
.queryParam("state", "#{stateValue}");
// with functions
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", session -> session.getString("milestoneValue"))
.queryParam("state", session -> session.getString("stateValue"));
// with static values
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "1")
.queryParam("state", "open")
// with Gatling EL strings
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "#{milestoneValue}")
.queryParam("state", "#{stateValue}")
// with functions
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone") { session -> session.getString("milestoneValue") }
.queryParam("state") { session -> session.getString("stateValue") }
// with static values
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "1")
.queryParam("state", "open")
// with Gatling EL strings
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "#{milestoneValue}")
.queryParam("state", "#{stateValue}")
// with functions
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", session => session("milestoneValue").as[String])
.queryParam("state", session => session("stateValue").as[String])
You can use multivaluedQueryParam
to set query parameters with multiple values:
http("name").get("/")
// with static values
.multivaluedQueryParam("param", Arrays.asList("value1", "value2"));
http("name").get("/")
// with a Gatling EL string pointing to a List
.multivaluedQueryParam("param", "#{values}");
http("name").get("/")
// with a function
.multivaluedQueryParam("param", session -> Arrays.asList("value1", "value2"));
http("name").get("/")
// with static values
.multivaluedQueryParam("param", listOf("value1", "value2"))
http("name").get("/")
// with a Gatling EL string pointing to a List
.multivaluedQueryParam("param", "#{values}")
http("name").get("/")
// with a function
.multivaluedQueryParam("param") { session -> listOf("value1", "value2") }
http("name").get("/")
// with static values
.multivaluedQueryParam("param", Seq("value1", "value2"))
http("name").get("/")
// with a Gatling EL string pointing to a Seq
.multivaluedQueryParam("param", "#{values}")
http("name").get("/")
// with a function
.multivaluedQueryParam("param", session => Seq("value1", "value2"))
You can use queryParamSeq
and queryParamMap
to set multiple query parameters at once:
http("name").get("/")
.queryParamSeq(Arrays.asList(
new AbstractMap.SimpleEntry("key1", "value1"),
new AbstractMap.SimpleEntry("key2", "value2")
)
);
Map<String, Object> params = new HashMap<>();
params.put("key1", "value1");
params.put("key2", "value2");
http("name").get("/")
.queryParamMap(params);
http("name").get("/")
.queryParamSeq(listOf(
AbstractMap.SimpleEntry<String, Any?>("key1", "value1"),
AbstractMap.SimpleEntry<String, Any?>("key2", "value2")
))
val params = mapOf(
"key1" to "value1",
"key2" to "value2"
)
http("name").get("/")
.queryParamMap(params)
http("name").get("/")
.queryParamSeq(Seq(("key1", "value1"), ("key2", "value2")))
http("name").get("/")
.queryParamMap(Map("key1" -> "value1", "key2" -> "value2"))
Headers
header
The HTTP protocol uses headers to exchange information between client and server that is not part of the message body.
Gatling HTTP allows you to specify any header you want to with the header
and headers
methods.
// Extracting a map of headers allows you to reuse these in several requests
Map<String, String> sentHeaders = new HashMap<>();
sentHeaders.put("content-type", "application/javascript");
sentHeaders.put("accept", "text/html");
http("name").get("/")
// Adds several headers at once
.headers(sentHeaders)
// Adds another header to the request
.header("keep-alive", "150")
// Overrides the content-type header
.header("content-type", "application/json");
// Extracting a map of headers allows you to reuse these in several requests
val sentHeaders = mapOf(
"content-type" to "application/javascript",
"accept" to "text/html"
)
http("name").get("/")
// Add several headers at once
.headers(sentHeaders)
// Adds another header to the request
.header("keep-alive", "150")
// Overrides the content-type header
.header("content-type", "application/json")
// Extracting a map of headers allows you to reuse these in several requests
val sentHeaders = Map(
"content-type" -> "application/javascript",
"accept" -> "text/html"
)
http("name").get("/")
// Adds several headers at once
.headers(sentHeaders)
// Adds another header to the request
.header("keep-alive", "150")
// Overrides the content-type header
.header("content-type", "application/json")
HttpHeaderNames.ContentType
.
You can find a list of the predefined constants here.asXXX
Gatling provides some handy shortcuts for setting the required headers for JSON, XML and form encodings:
// asJson
http("name").post("/")
.asJson();
// is a shortcut for:
http("name").post("/")
.header("accept", "application/json")
.header("content-type", "application/json");
// asXml
http("name").post("/")
.asXml();
// is a shortcut for:
http("name").post("/")
.header("accept", "application/xhtml+xml")
.header("content-type", "application/xhtml+xml");
// asFormUrlEncoded
http("name").post("/")
.asFormUrlEncoded();
// is a shortcut for:
http("name").post("/")
.header("content-type", "application/application/x-www-form-urlencoded");
// asMultipartForm
http("name").post("/")
.asMultipartForm();
// is a shortcut for:
http("name").post("/")
.header("content-type", "multipart/form-data");
// asJson
http("name").post("/")
.asJson()
// is a shortcut for:
http("name").post("/")
.header("accept", "application/json")
.header("content-type", "application/json")
// asXml
http("name").post("/")
.asXml()
// is a shortcut for:
http("name").post("/")
.header("accept", "application/xhtml+xml")
.header("content-type", "application/xhtml+xml")
// asFormUrlEncoded
http("name").post("/")
.asFormUrlEncoded()
// is a shortcut for:
http("name").post("/")
.header("content-type", "application/application/x-www-form-urlencoded")
// asMultipartForm
http("name").post("/")
.asMultipartForm()
// is a shortcut for:
http("name").post("/")
.header("content-type", "multipart/form-data")
// asJson
http("name").post("/")
.asJson
// is a shortcut for:
http("name").post("/")
.header("accept", "application/json")
.header("content-type", "application/json")
// asXml
http("name").post("/")
.asXml
// is a shortcut for:
http("name").post("/")
.header("accept", "application/xhtml+xml")
.header("content-type", "application/xhtml+xml")
// asFormUrlEncoded
http("name").post("/")
.asFormUrlEncoded
// is a shortcut for:
http("name").post("/")
.header("content-type", "application/application/x-www-form-urlencoded")
// asMultipartForm
http("name").post("/")
.asMultipartForm
// is a shortcut for:
http("name").post("/")
.header("content-type", "multipart/form-data")
HttpProtocol
.For a given request, you can also disable shared HttpProtocol
headers with ignoreProtocolHeaders
.
http("name").get("/")
.ignoreProtocolHeaders();
http("name").get("/")
.ignoreProtocolHeaders()
http("name").get("/")
.ignoreProtocolHeaders
Checks
You can add checks on a request.
http("name").get("/")
.check(status().is(200));
http("name").get("/")
.check(status().shouldBe(200))
http("name").get("/")
.check(status.is(200))
For more information, see the HTTP Checks reference section.
For a given request, you can also disable common checks that were defined on the HttpProtocol
with ignoreProtocolChecks
:
http("name").get("/")
.ignoreProtocolChecks();
http("name").get("/")
.ignoreProtocolChecks()
http("name").get("/")
.ignoreProtocolChecks
Request Body
Full Body
In this section, you can find the various methods for setting the full request body.
Body templates location are resolved the same way as for Feeder files.
Files must be placed in:
- the
user-files/resources
directory when using the bundle distribution src/main/resources
orsrc/test/resources
when using a maven, gradle or sbt project
src/main/resources/data/foo.txt
data/foo.txt
.You can add a full body to an HTTP request with the dedicated method body
, where body can be:
StringBody
StringBody
lets you pass a text payload defined in your code.
The charset used writing the bytes on the wire is the one defined in the charset
attribute of the Content-Type
request header if defined, otherwise the one defined in gatling.conf
.
This solution is typically used with Strings in the Gatling Expression Language format.
It takes one single parameter:
string
the text content, can be a plainString
, a Gatling Expression LanguageString
or a function.
// with a static payload
http("name").post("/")
.body(StringBody("{ \"foo\": \"staticValue\" }"));
// with a Gatling EL string payload
http("name").post("/")
.body(StringBody("{ \"foo\": \"#{dynamicValue}\" }"));
// with a function payload
http("name").post("/")
.body(StringBody(session -> "{ \"foo\": \"" + session.getString("dynamicValueKey") + "\" }"));
// with a static payload
http("name").post("/")
.body(StringBody("""{ "foo": "staticValue" }"""))
// with a Gatling EL string payload
http("name").post("/")
.body(StringBody("""{ "foo": "#{dynamicValue}" }"""))
// with a function payload
http("name").post("/")
.body(StringBody { session -> """{ "foo": "${session.getString("dynamicValueKey")}" }""" })
// with a static payload
http("name").post("/")
.body(StringBody("""{ "foo": "staticValue" }"""))
// with a Gatling EL string payload
http("name").post("/")
.body(StringBody("""{ "foo": "#{dynamicValue}" }"""))
// with a function payload
http("name").post("/")
.body(StringBody(session => s"""{ "foo": "${session("dynamicValueKey").as[String]}" }"""))
Using function is one way to craft complex dynamic payload as you can code your own logic.
static final class Templates {
public static final Function<Session, String> template = session -> {
String foo = session.getString("foo");
String bar = session.getString("bar");
return "{ \"foo\": \"" + foo + "\", \"bar\": \"" + bar + "\" }";
};
}
http("name").post("/")
.body(StringBody(Templates.template));
internal object Templates {
val template = Function { session: Session ->
val foo = session.getString("foo")
val bar = session.getString("bar")
"""{ "foo": "$foo", "bar": "$bar" }"""
}
}
http("name").post("/")
.body(StringBody(HttpRequestSampleJava.Templates.template))
object Templates {
val template: Expression[String] = session =>
for {
foo <- session("foo").validate[String]
bar <- session("bar").validate[String]
} yield s"""{ "foo": "$foo", "bar": "$bar" }"""
}
http("name").post("/")
.body(StringBody(Templates.template))
RawFileBody
RawFileBody
lets you pass a raw file whose bytes will be sent as is, meaning it can be binary content.
This way is the most efficient one as bytes can be cached and don’t have to be decoded into text and then re-encoded back into bytes to be written on the wire.
It takes one single parameter:
filePath
the file location, can be a plainString
, a Gatling Expression LanguageString
or a function.
// with a static path
http("name").post("/")
.body(RawFileBody("rawPayload.json"));
// with a Gatling EL String path
http("name").post("/")
.body(RawFileBody("#{payloadPath}"));
// with a function path
http("name").post("/")
.body(RawFileBody(session -> session.getString("payloadPath")));
// with a static path
http("name").post("/")
.body(RawFileBody("rawPayload.json"))
// with a Gatling EL String path
http("name").post("/")
.body(RawFileBody("#{payloadPath}"))
// with a function path
http("name").post("/")
.body(RawFileBody { session -> session.getString("payloadPath") })
// with a static path
http("name").post("/")
.body(RawFileBody("rawPayload.json"))
// with a Gatling EL String path
http("name").post("/")
.body(RawFileBody("#{payloadPath}"))
// with a function path
http("name").post("/")
.body(RawFileBody(session => session("payloadPath").as[String]))
ElFileBody
ElFileBody
lets you pass some text content resolved from a template file in the Gatling Expression Language format.
It takes one single parameter:
filePath
the file location, can be a plainString
, a Gatling Expression LanguageString
or a function.
As Gatling EL is a text based templating engine, content can not be non-textual.
http("name").post("/")
.body(ElFileBody("rawPayload.json"));
// with a Gatling EL String path
http("name").post("/")
.body(ElFileBody("#{payloadPath}"));
// with a function path
http("name").post("/")
.body(ElFileBody(session -> session.getString("payloadPath")));
http("name").post("/")
.body(ElFileBody("rawPayload.json"))
// with a Gatling EL String path
http("name").post("/")
.body(ElFileBody("#{payloadPath}"))
// with a function path
http("name").post("/")
.body(ElFileBody { session -> session.getString("payloadPath") })
http("name").post("/")
.body(ElFileBody("rawPayload.json"))
// with a Gatling EL String path
http("name").post("/")
.body(ElFileBody("#{payloadPath}"))
// with a function path
http("name").post("/")
.body(ElFileBody(session => session("payloadPath").as[String]))
PebbleStringBody
Gatling Expression Language is definitively the most optimized templating engine for Gatling, in terms of raw performance. However, it’s a bit limited in terms of logic you can implement in there. If you want loops and conditional blocks, you can use Gatling’s Pebble based templating engine.
http("name").post("/")
.body(PebbleStringBody("{ \"foo\": \"{% if someCondition %}{{someValue}}{% endif %}\" }"));
http("name").post("/")
.body(PebbleStringBody("{ \"foo\": \"{% if someCondition %}{{someValue}}{% endif %}\" }"))
http("name").post("/")
.body(PebbleStringBody("""{ "foo": "{% if someCondition %}{{someValue}}{% endif %}" }"""))
Extensions
s with registerPebbleExtensions(extensions: Extension*)
. This can only be done once, and must be done prior to loading any Pebble template.PebbleFileBody
.PebbleFileBody
PebbleFileBody
lets you pass the path to a Pebble file template.
// with a static value path
http("name").post("/")
.body(PebbleFileBody("pebbleTemplate.json"));
// with a Gatling EL string path
http("name").post("/")
.body(PebbleFileBody("#{templatePath}"));
// with a function path
http("name").post("/")
.body(PebbleFileBody(session -> session.getString("templatePath")));
// with a static value path
http("name").post("/")
.body(PebbleFileBody("pebbleTemplate.json"))
// with a Gatling EL string path
http("name").post("/")
.body(PebbleFileBody("#{templatePath}"))
// with a function path
http("name").post("/")
.body(PebbleFileBody { session -> session.getString("templatePath") })
// with a static value path
http("name").post("/")
.body(PebbleFileBody("pebbleTemplate.json"))
// with a Gatling EL string path
http("name").post("/")
.body(PebbleFileBody("#{templatePath}"))
// with a function path
http("name").post("/")
.body(PebbleFileBody(session => session("templatePath").as[String]))
ByteArrayBody
ByteArrayBody
lets you pass an array of bytes, typically when you want to use a binary protocol such as Protobuf.
// with a static value
http("name").post("/")
.body(ByteArrayBody(new byte[] { 0, 1, 5, 4 }));
// with a static value
http("name").post("/")
.body(ByteArrayBody("#{bytes}"));
// with a function
http("name").post("/")
.body(ByteArrayBody(session ->
Base64.getDecoder().decode(session.getString("data")))
);
// with a static value
http("name").post("/")
.body(ByteArrayBody(byteArrayOf(0, 1, 5, 4)))
// with a static value
http("name").post("/")
.body(ByteArrayBody("#{bytes}"))
// with a function
http("name").post("/")
.body(ByteArrayBody { session -> Base64.getDecoder().decode(session.getString("data")) }
)
// with a static value
http("name").post("/")
.body(ByteArrayBody(Array[Byte](0, 1, 5, 4)))
// with a static value
http("name").post("/")
.body(ByteArrayBody("#{bytes}"))
// with a function
http("name").post("/")
.body(ByteArrayBody(session =>
Base64.getDecoder.decode(session("data").as[String]))
)
InputStreamBody
InputStreamBody
lets you pass an java.util.InputStream
.
http("name").post("/")
.body(InputStreamBody(session -> new ByteArrayInputStream(new byte[] { 0, 1, 5, 4 })));
http("name").post("/")
.body(InputStreamBody { session -> ByteArrayInputStream(byteArrayOf(0, 1, 5, 4)) })
http("name").post("/")
.body(InputStreamBody(session => new ByteArrayInputStream(Array[Byte](0, 1, 5, 4))))
Forms
This section refers to payloads encoded with application/x-www-form-urlencoded
or multipart/form-data
, used with HTML forms.
Unless you’ve explicitly set the Content-Type
header:
- if you’ve set at least one file part, Gatling will set it to
multipart/form-data
- otherwise, it will set it to
application/x-www-form-urlencoded
.
formParam
formParam
lets you pass non file form input fields.
// with static values
http("name").post("/")
.formParam("milestone", "1")
.formParam("state", "open");
// with Gatling EL strings
http("name").post("/")
.formParam("milestone", "#{milestoneValue}")
.formParam("state", "#{stateValue}");
// with functions
http("name").post("/")
.formParam("milestone", session -> session.getString("milestoneValue"))
.formParam("state", session -> session.getString("stateValue"));
// with static values
http("name").post("/")
.formParam("milestone", "1")
.formParam("state", "open")
// with Gatling EL strings
http("name").post("/")
.formParam("milestone", "#{milestoneValue}")
.formParam("state", "#{stateValue}")
// with functions
http("name").post("/")
.formParam("milestone") { session -> session.getString("milestoneValue") }
.formParam("state") { session -> session.getString("stateValue") }
// with static values
http("name").post("/")
.formParam("milestone", "1")
.formParam("state", "open")
// with Gatling EL strings
http("name").post("/")
.formParam("milestone", "#{milestoneValue}")
.formParam("state", "#{stateValue}")
// with functions
http("name").post("/")
.formParam("milestone", session => session("milestoneValue").as[String])
.formParam("state", session => session("stateValue").as[String])
You can use multivaluedFormParam
to set form parameters with multiple values:
http("name").post("/")
// with static values
.multivaluedFormParam("param", Arrays.asList("value1", "value2"));
http("name").post("/")
// with a Gatling EL string pointing to a List
.multivaluedFormParam("param", "#{values}");
http("name").post("/")
// with a function
.multivaluedFormParam("param", session -> Arrays.asList("value1", "value2"));
http("name").post("/") // with static values
.multivaluedFormParam("param", Arrays.asList<Any>("value1", "value2"))
http("name").post("/") // with a Gatling EL string pointing to a List
.multivaluedFormParam("param", "#{values}")
http("name").post("/") // with a function
.multivaluedFormParam("param") { session -> listOf("value1", "value2") }
http("name").post("/")
// with static values
.multivaluedFormParam("param", Seq("value1", "value2"))
http("name").post("/")
// with a Gatling EL string pointing to a Seq
.multivaluedFormParam("param", "#{values}")
http("name").post("/")
// with a function
.multivaluedFormParam("param", session => Seq("value1", "value2"))
You can use formParamSeq
and formParamMap
to set multiple form parameters at once:
http("name").get("/")
.formParamSeq(Arrays.asList(
new AbstractMap.SimpleEntry("key1", "value1"),
new AbstractMap.SimpleEntry("key2", "value2")
)
);
Map<String, Object> params = new HashMap<>();
params.put("key1", "value1");
params.put("key2", "value2");
http("name").get("/")
.formParamMap(params);
http("name").get("/")
.formParamSeq(listOf(
AbstractMap.SimpleEntry<String, String>("key1", "value1"),
AbstractMap.SimpleEntry<String, String>("key2", "value2")
))
http("name").get("/")
.formParamMap(mapOf("key1" to "value1", "key2" to "value2"))
http("name").post("/")
.formParamSeq(Seq(("key1", "value1"), ("key2", "value2")))
http("name").post("/")
.formParamMap(Map("key1" -> "value1", "key2" -> "value2"))
form
You might want to repost all the inputs or a form previously captured with a form
check.
Note you can override the form field values with the formParam
and the likes.
http("name").post("/")
.form("#{previouslyCapturedForm}")
// override an input
.formParam("fieldToOverride", "newValue");
http("name").post("/")
.form("#{previouslyCapturedForm}") // override an input
.formParam("fieldToOverride", "newValue")
http("name").post("/")
.form("#{previouslyCapturedForm}")
// override an input
.formParam("fieldToOverride", "newValue")
formUpload
This method takes 2 parameters:
- name the name of the form input, can be a plain
String
, a Gatling Expression LanguageString
or a function. - filePath the path to the file, can be a plain
String
, a Gatling Expression LanguageString
or a function.
See above how Gatling resolves filePath
.
// with a static filepath value
http("name").post("/")
.formParam("key", "value")
.formUpload("file1", "file1.dat")
// you can set multiple files
.formUpload("file2", "file2.dat");
// with a Gatling EL string filepath
http("name").post("/")
.formUpload("file1", "#{file1Path}");
// with a function filepath
http("name").post("/")
.formUpload("file1", session -> session.getString("file1Path"));
// with a static filepath value
http("name").post("/")
.formParam("key", "value")
.formUpload("file1", "file1.dat")
// you can set multiple files
.formUpload("file2", "file2.dat")
// with a Gatling EL string filepath
http("name").post("/")
.formUpload("file1", "#{file1Path}")
// with a function filepath
http("name").post("/")
.formUpload("file1") { session -> session.getString("file1Path") }
// with a static filepath value
http("name").post("/")
.formParam("key", "value")
.formUpload("file1", "file1.dat")
// you can set multiple files
.formUpload("file2", "file2.dat")
// with a Gatling EL string filepath
http("name").post("/")
.formUpload("file1", "#{file1Path}")
// with a function filepath
http("name").post("/")
.formUpload("file1", session => session("file1Path").as[String])
application/octet-stream
and the character set defaults to the one configured in gatling.conf
(UTF-8
by default). Override them when needed.Multipart
bodyPart
You can set a multipart body as individual parts using bodyPart
.
// set a single part
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
);
// set a multiple parts
http("name").post("/")
.bodyParts(
StringBodyPart("partName1", "value"),
StringBodyPart("partName2", "value")
);
// set a single part
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
)
// set a multiple parts
http("name").post("/")
.bodyParts(
StringBodyPart("partName1", "value"),
StringBodyPart("partName2", "value")
)
// set a single part
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
)
// set a multiple parts
http("name").post("/")
.bodyParts(
StringBodyPart("partName1", "value"),
StringBodyPart("partName2", "value")
)
Once bootstrapped with one of the following methods, BodyPart
has the following methods for setting additional options.
Like in the rest of the DSL, almost every parameter can be a plain String
, a Gatling Expression Language String
or a function.
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
.contentType("contentType")
.charset("utf-8")
// part of the Content-Disposition header
.fileName("fileName")
// defaults to "form-data"
.dispositionType("dispositionType")
.contentId("contentId")
.transferEncoding("transferEncoding")
.header("name", "value")
);
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
.contentType("contentType")
.charset("utf-8")
// part of the Content-Disposition header
.fileName("fileName")
// defaults to "form-data"
.dispositionType("dispositionType")
.contentId("contentId")
.transferEncoding("transferEncoding")
.header("name", "value")
)
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
.contentType("contentType")
.charset("utf-8")
// part of the Content-Disposition header
.fileName("fileName")
// defaults to "form-data"
.dispositionType("dispositionType")
.contentId("contentId")
.transferEncoding("transferEncoding")
.header("name", "value")
)
StringBodyPart
Similar to StringBody.
RawFileBodyPart
where path is the location of a file that will be uploaded as is.
Similar to RawFileBody.
ElFileBodyPart
where path is the location of a file whose content will be parsed and resolved with Gatling EL engine.
Similar to ElFileBody.
PebbleStringBodyPart
Similar to PebbleStringBody.
PebbleFileBodyPart
Similar to PebbleFileBody.
ByteArrayBodyPart
Similar to ByteArrayBody.
Pre-Processing
processRequestBody
You might want to process the request body before it’s being sent to the wire.
Gatling currently only provides one single pre-processor: gzipBody
.
http("name").post("/")
.body(RawFileBody("file"))
.processRequestBody(gzipBody);
http("name").post("/")
.body(RawFileBody("file"))
.processRequestBody(gzipBody)
http("name").post("/")
.body(RawFileBody("file"))
.processRequestBody(gzipBody)
Resources
Gatling can fetch a main request’s resources in parallel in order to emulate the behavior of a real web browser.
http("name").post("/")
.resources(
http("api.js").get("/assets/api.js"),
http("ga.js").get("/ga.js")
);
http("name").post("/")
.resources(
http("api.js")["/assets/api.js"],
http("ga.js")["/ga.js"]
)
http("name").get("/")
.resources(
http("api.js").get("/assets/api.js"),
http("ga.js").get("/ga.js")
)
Advanced Options
requestTimeout
The default request timeout is controlled by the ``gatling.http.requestTimeout` configuration parameter.
However, you might want to use requestTimeout
to override the global value for a specific request, typically a long file upload or download.
http("name").get("/")
.requestTimeout(Duration.ofMinutes(3));
http("name").get("/")
.requestTimeout(Duration.ofMinutes(3))
http("name").get("/")
.requestTimeout(3.minutes)
basicAuth
and digestAuth
Just like you can define a global basicAuth
or digestAuth
on the HttpProtocol configuration, you can define one on individual requests.
proxy
Just like you can globally define a proxy
on the HttpProtocol configuration, you can define one on individual requests.
virtualHost
Just like you can globally define a virtualHost
on the HttpProtocol configuration, you can define one on individual requests.
disableFollowRedirect
Just like you can globally disable following redirect on the HttpProtocol configuration, you can define one on individual requests.
disableUrlEncoding
Just like you can globally disable URL encoding on the HttpProtocol configuration, you can define one on individual requests.
silent
See silencing protocol section for more details.
You can then make the request silent:
http("name").get("/")
.silent();
http("name").get("/")
.silent()
http("name").get("/")
.silent
You might also want to do the exact opposite, typically on a given resource while resources have been globally turned silent at protocol level:
.resources(
http("resource").get("/assets/images/img1.png")
.notSilent()
);
.resources(
http("resource").get("/assets/images/img1.png")
.notSilent()
)
.resources(
http("resource").get("/assets/images/img1.png")
.notSilent
)
sign
Just like you can define a global signing strategy on the HttpProtocol configuration, you can define one on individual requests.
transformResponse
Similarly, one might want to process the response before it’s passed to the checks pipeline:
transformResponse(responseTransformer: (Response, Session) => Validation[Response])
The example below shows how to decode some Base64 encoded response body:
//import io.gatling.http.response.*;
//
//import java.nio.charset.StandardCharsets.UTF_8
//import java.util.Base64
// ignore when response status code is not 200
.transformResponse((response, session) -> {
if (response.status().code() == 200) {
return new io.gatling.http.response.Response(
response.request(),
response.startTimestamp(),
response.endTimestamp(),
response.status(),
response.headers(),
new io.gatling.http.response.ByteArrayResponseBody(Base64.getDecoder().decode(response.body().string()), StandardCharsets.UTF_8),
response.checksums(),
response.isHttp2()
);
} else {
return response;
}
}
);
//import io.gatling.http.response.*;
//
//import java.nio.charset.StandardCharsets.UTF_8
//import java.util.Base64
// ignore when response status code is not 200
.transformResponse { response, session ->
if (response.status().code() == 200) {
return@transformResponse Response(
response.request(),
response.startTimestamp(),
response.endTimestamp(),
response.status(),
response.headers(),
ByteArrayResponseBody(Base64.getDecoder().decode(response.body().string()), StandardCharsets.UTF_8),
response.checksums(),
response.isHttp2
)
} else {
return@transformResponse response
}
}
import java.nio.charset.StandardCharsets.UTF_8
import java.util.Base64
import io.gatling.http.response._
// ignore when response status code is not 200
.transformResponse {
(response, session) =>
if (response.status.code == 200) {
response.copy(body = new ByteArrayResponseBody(Base64.getDecoder.decode(response.body.string), UTF_8))
} else {
response
}
}