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

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.

Related

loop with requests.get and avoid timeout errors

I am trying to get scrape information.
I goto the introduction page to determine the number of search results. Often, the results occur over >1 page, and as such, I need to refresh and run another requests in a loop. On a few occasions an error occurs in the extra requests, or it hangs.
I am curious if there is a way to check a request, if it fails, then try again, and if it still fails, log it and go to the next one
Here is a sample script:
t=.3
urls=['https://stackoverflow.com/','https://www.google.com/'] #list of upto 200 urls
for url in urls:
print(url)
response = requests.get(url, timeout=t)
t=t+10
i=i-1
running this returns a timeout occasionally, and the processing stops. My workaround is to print the url that failed, and then rerun, updating the list manually.
I would like to find a way that if a request error occurs, the response retries 5x, and if it fails, logs and stores the failed url, then goes onto the next one, so that I can try the failed urls at a later stage
Any suggestions?
I haven't used Python in a while, but I'm pretty sure that this will work.
t=.3
urls=['https://stackoverflow.com/','https://www.google.com/'] #list of upto 200 urls
for url in urls:
print(url)
try:
response = requests.get(url, timeout=t)
except:
# if the request fails: try again
try:
response = requests.get(url, timeout=t)
except:
# if the request fails again: do nothing (continue to the next url)
pass
t=t+10
i=i-1

how to store bearer token in cookies in react js frontend

I am using React JS for the front-end part of my code. I want to store the bearer token in cookies and then return the bearer token in the content field when the API is called successfully. As I haven't used cookies earlier so want to know how I can accomplish this task. Also the back-end part is not done by me.
Following is the code in which I am calling the API
onSubmitSignup = () => {
fetch('https://cors-anywhere.herokuapp.com/http://35.154.16.105:8080/signup/checkMobile',{
method:'post',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({
mobile:this.state.mobile
})
})
.then(response => response.json())
.then(data =>{
if(data.statusCode === '2000'){
localStorage.setItem('mobile',this.state.mobile);
// this.props.loadNewUser(this.state.mobile);
this.props.onRouteChange('otp','nonav');
}
})
// this.props.onRouteChange('otp','nonav');
}
First of all, on this line:
if(data.statusCode === '2000'){
Are you sure the status code shouldn't be 200 and not 2000.
Secondly, there are packages for managing cookies. One that springs to mind is:
Link to GitHub "Universal Cookie" repo
However you can use vanilla js to manage cookies, more info can be found on the Mozilla website:
Here
When you make that initial API call, within the data returned, I assume the Bearer token is returned too. Initialise the cookie there like so:
document.cookie = "Bearer=example-bearer-token;"
When you need access to the cookie at a later date, you can just use the following code:
const cookieValue = document.cookie
.split('; ')
.find(row => row.startsWith('Bearer'))
.split('=')[1];
And then forward the bearer with the next call.
Edit
Set the cookie bearer token like this:
document.cookie = "Bearer=example-bearer-token;"
Get the cookie bearer token like this:
const cookieValue = document.cookie
.split('; ')
.find(row => row.startsWith('Bearer'))
.split('=')[1];
A cookie is made up of key/value pairs separated by a semi-colon. Therefore the above code to get the "Bearer" value, firstly gets the cookie, splits it into its key/value pairs, finds the row that has a key of "Bearer" and splits that row to attain the Bearer token.
In your comment you say the dev team said the bearer will be in the "content". In your ajax request you already have access to that content through data. You need to debug that request to find out what it is coming back as. I assume you just need to grab the token from the returned data inside of the "If" block where you check for your statusCode.
It will be something like:
document.cookie = "Bearer=" + data.bearer;
However, I don't have the shape of your data so you can only work that final part out yourself.

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);

CakePHP 403 on AJAX request

I'm trying to use AJAX to autocomplete a search box on my website. I was using firebug to test my application. When I try to search something, Firebug tells me that the AJAX request returned a 403 forbidden error. However, when I copy the EXACT URL that was in the AJAX request, it returns the correct data.
Edit:
I think this has to be something on the JavaScript side. Are there any headers that might be omitted with an AJAX request compared to a normal request?
Here is the $_SERVER variable (I removed the parameters that were the same on both requests) on an AJAX request that failed (1) vs typing the URL in and it works (2):
(1)
2011-04-02 13:43:07 Debug: Array
(
[HTTP_ACCEPT] => */*
[HTTP_COOKIE] => CAKEPHP=0f9d8dc4cd49e5ca0f1a25dbd6635bac;
[HTTP_X_REQUESTED_WITH] => XMLHttpRequest
[REDIRECT_REDIRECT_UNIQUE_ID] => TZdgK654EmIAAEjknsMAAAFG
[REDIRECT_UNIQUE_ID] => TZdgK654EmIAAEjknsMAAAFG
[REMOTE_PORT] => 60252
[UNIQUE_ID] => TZdgK654EmIAAEjknsMAAAFG
[REQUEST_TIME] => 1301766187
)
(2)
2011-04-02 13:44:02 Debug: Array
(
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[HTTP_COOKIE] => CAKEPHP=d8b392a5c3ee8dd948cee656240fd5ea;
[REDIRECT_REDIRECT_UNIQUE_ID] => TZdgYq54EmIAAF7zt6wAAAJJ
[REDIRECT_UNIQUE_ID] => TZdgYq54EmIAAF7zt6wAAAJJ
[REMOTE_PORT] => 60281
[UNIQUE_ID] => TZdgYq54EmIAAF7zt6wAAAJJ
[REQUEST_TIME] => 1301766242
)
I think I found the solution. I set the security level to medium to solve the issue. I found this line in the config folder. Does a medium security level pose any problems in production?
/**
* The level of CakePHP security. The session timeout time defined
* in 'Session.timeout' is multiplied according to the settings here.
* Valid values:
*
* 'high' Session timeout in 'Session.timeout' x 10
* 'medium' Session timeout in 'Session.timeout' x 100
* 'low' Session timeout in 'Session.timeout' x 300
*
* CakePHP session IDs are also regenerated between requests if
* 'Security.level' is set to 'high'.
*/
Configure::write('Security.level', 'medium');
Edit: This is definitely the solution. Here's what was happening:
When the security level is set to high, a new session ID is generated upon every request.
That means that when I was making ajax requests, a new session ID would be generated.
If you stay on the same page, JavaScript makes a request, which generates a new session_id, and doesn't record the new session_id.
All subsequent ajax requests use an old session_id, which is declared invalid, and returns an empty session.
If you are using Auth, you need to make sure that you are logged in if the controller/action is not on your $this->Auth->allow() list.
Make sure you set debug to 0 as well, might cause you some problems.
Maybe it's the Cross site request forgery component. It's responsible for all authentication requests, except GET requests. Look at this: http://book.cakephp.org/3.0/en/controllers/components/csrf.html

Resources