How to get request and response size in gatling - gatling

In Postman I can see request and response size
How do I get this in gatling ?
I need to validate the size.

You can validate size via check and bodyLength where pass expected size in bytes.
val request = http("request")
.get("localhost")
.check(
bodyLength.is(221)
)

Related

Gatling overrides `Cookie` header with the `Set-Cookie` header of previous response

I have an http request in Gatling that gets executed 10 times:
val scnProxy = scenario("Access proxy")
.exec(session => session.set("connect.sid", sessionId))
.repeat(10) {
exec(
http("Access endpoint")
.get("/my-api")
.header(
"Cookie",
session => "connect.sid=" + session("connect.sid").as[String]
)
.check(status is 200)
)
}
For some reason, I get the intended response only on the first iteration. On every other iteration, I keep getting 401. So, I changed log level to TRACE to see what the problem is and found a weird behavior. For the first iteration, I get the header Cookie: connect.sid=... but for some reason, on second and other iterations, the cookie parameter gets overridden by the set-cookie of the previous request. Since Cookie header value is a string, it does not merge these cookies.
Is there a way that I can add a cookie instead of my cookie getting overriden?
Use the proper Gatling components for manipulating cookies.

How to take value of a variable in Gatling script

I have extracted token value from the login api call.but i am not able to use that variable value into next api call.My code is given below
val scn = scenario("test login")
.exec(http("login call")
.post("https://api.k6.io/v3/account/login")
.headers(headers_1)
.body(RawFileBody("data/login.json"))
.check(status.is(200))
.check(jsonPath("$.token.key").saveAs("tokenId")))
.pause(21)
.exec(http("edit profile call")
.post("https://api.k6.io/v3/users/3187878")
.headers(headers_1)
.header("Authorization", "Token ${tokenId}")
.body(RawFileBody("data/editprofile.json"))
.check(status.is(200)))
but the call get failed. I am not getting the value of that variable in the second call.
{"key":"4c713e3f5d362f0002f6eef737401e249c154bed"}
i need to use the value of 'key' in the header for next api call as in the format of
.header("Authorization", "Token 4c713e3f5d362f0002f6eef737401e249c154bed")
but it is not getting in this format.where i am going wrong?Can anyone help me.Thanks in advance
Your way of capturing data with a check and re-injecting it with Gatling Expression Language is correct.
Possible reasons your scenario doesn't work:
the "login call" request fails and is not able to capture the data
you use RawFileBody but maybe some data in there needs to be dynamic, just like your Authorization header
If you want to check what's been captured, you can add an extra action before your pause:
.exec { session =>
println(session("tokenId").as[String])
session
}

How can an HTTP 403 be returned from an apache web server input filter?

I have written an apache 2.x module that attempts to scan request bodies, and conditionally return 403 Forbidden if certain patterns match.
My first attempt used ap_hook_handler to intercept the request, scan it and then returned DECLINED to the real handler could take over (or 403 if conditions were met).
Problem with that approach is when I read the POST body of the request (using ap_get_client_block and friends), it apparently consumed body so that if the request was subsequently handled by mod_proxy, the body was gone.
I think the right way to scan the body would be to use an input filter, except an input filter can only return APR_SUCCESS or fail. Any return codes other than APR_SUCCESS get translated into HTTP 400 Bad Request.
I think maybe I can store a flag in the request notes if the input filter wants to fail the request, but I'm not sure which later hook to get that.
turned out to be pretty easy - just drop an error bucket into the brigade:
apr_bucket_brigade *brigade = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc);
apr_bucket *bucket = ap_bucket_error_create(403, NULL, f->r->pool,
f->r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
bucket = apr_bucket_eos_create(f->r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
ap_pass_brigade(f->next, brigade);

What is the size limit of email body in messages.send method of Gmail API?

I am using official .net api client to send emails with attachments by messages.send method. When I attach a file of size more than approximately 5mb, I've come to
[JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.]
Newtonsoft.Json.JsonTextReader.ParseValue() +1187
Newtonsoft.Json.JsonTextReader.ReadInternal() +65
Newtonsoft.Json.JsonTextReader.Read() +28
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) +237
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) +783
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) +293
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) +274
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) +57
Google.Apis.Json.NewtonsoftJsonSerializer.Deserialize(String input) in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis.Core\Apis\Json\NewtonsoftJsonSerializer.cs:120
Google.Apis.Services.<DeserializeError>d__8.MoveNext() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\Services\BaseClientService.cs:286
[GoogleApiException: An Error occurred, but the error response could not be deserialized]
Google.Apis.Requests.ClientServiceRequest`1.Execute() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\Requests\ClientServiceRequest.cs:102
I think client use Metadata URI, for metadata-only requests. A am going to try another option: Upload URI, for media upload requests.
It looks like there is a limit on email size that leads to exception of parsing error response in the client library.
So, the first question: is there a size limit?
Second, there is no info about how to use different upload methods via client, do you know any client library documentation?
Update: I hacked that request produced by
var request = gmailService.Users.Messages.Send(message, AccountUserId);
is going to https://www.googleapis.com/gmail/v1/users/me/messages/send. As I supposed it didn't use media upload request.
I ended up with limit on attachments total size. Here is code snippet.
Class level:
public const int MaxAttachmentsSize = 5 * 1024 * 1024;
Method level:
var attachmentsSize = 0;
foreach (var attachment in attachments)
{
attachmentsSize += attachment.Item1;
if (attachmentsSize > MaxAttachmentsSize) break;
mailMessage.Attachments.Add(attachment.Item2);
}
There is limit in MB of whole message. Google API allows you for quite big email but it may get timeout when sending if your service because of connection speed will be doing it too long.
According to this google docs it is 35MB:
google api send docs
For anything (uploading) over a few MB you should definitely use the /upload version of the method, otherwise yes you may run into those size limitations.
In response to the second part of your question...
Second, there is no info about how to use different upload methods via client, do you know any client library documentation?
I did a little poking around in the API, and I see that there is also a method that takes a stream as the 3rd parameter.
services.Users.Messages.Send( body, userId, stream, contentType)
Digging into the source code of that, I see that it seems to use a URL that looks like:
upload/....
I haven't tried it yet, and I don't know (yet) what it wants for a "stream", but this looks like a good possibility for getting a resumable upload with a bigger limit.

Get auth token in Gatling

I'm trying to use Gatling to test my API but I've got a problem. I'm testing for now the login/logout. At the login, the user got a token, that is used for logout.
When I use the recorder, it keep a fix token, and of course, it doesn't work when I run the test. But I don't find in the doc or google how I can get dynamically the token.
Does anyone know ?
Thanks !
EDIT:
after recording here what I got
val headers_13 = Map(
"Accept" -> """*/*""",
"Origin" -> """http://site.com""",
"token" -> """token"""
)
val scn = scenario("Scenario Name")
.exec(http("request_1")
.post("http://site.com/login")
.headers(headers_1)
.param("""player[email]""", """email#address.com""")
.param("""player[password]""", """password""")
)
.pause(757 milliseconds)
…
.exec(http("request_13")
.get("http://site.com/logout")
.headers(headers_13)
)
.pause(202 milliseconds)
I try to put the two pieces of code after .post("http://site.com/login") and .get("http://site.com/logout") but that didn't works
Where is your token? Is it a HTTP header?
Generally speaking, the way to save data from responses in order to reuse it for further requests is the Check API.
.check(header("tokenName").saveAs("token")
...
.header("tokenName", "${token}")

Resources