Pass Content and Attributes from 2 different Processors to InvokeHttp Processor - apache-nifi

Here is what i am trying to do
Get a file and encode it to base 64
Login to API and get OAUTH token for subsequent API calls (Since Invoke HTTP doesnt take a body so i have to pass a body using GenerateFlow processor before that)
Both Steps 1 and 2 are interchangeable
Now i need the token from the login call as Header value and Base64 encoded file as the body to the next Invoke Processor.
The problem is i am not able to connect the flows 1 and 2 so i can take them to step 3 where i need to invoke another API using the data from the 2. Both GetFile and GenerateFlow are source processors.
Here is what i am thinking, to somehow convert the content to attribute. Since the file is encoded in base64, is there a way i can convert that content to attribute? i am trying to but the content is just random text, i am not sure what param to look for or what i need to put that to. is there a way to say convert whatever is in the content to an attribute say filecontent="all the flow-content"
nifi-flow-snapshot
Base 64 encoded content

First trigger both flow fro mthe same generateflowfie >> updateattribute(create common attribute to be used in merge correlation).
Do your work
Use MergeContent - keep all unique attribute - Set correlaion using the common attribute set in out first step.

This is how i resolved my issue for now. There may be other better ways but this one worked.
Start the flow with
GetFile>>Base64Encode>>ExtractText>>ReplaceText>>Login>>continue
with rest of the flow
The trick that work was to place the ReplaceText so it can grab the entire base64 encoded content and place it in an attribute. then ReplaceText will replace the entire content with the body of the login processor.
Now i have both login token and base 64 encoded file which i can send to my next processors.
Thanks

Related

Jmeter 5.3: Extract run time 'code_challenge' URL parameter value from request URL which is not shown in any response

We have one URL parameter as "code_challenge" which gets generated at run time, this value we need to extract so that from next runs it can be handled. However since this code value is not captured in any previous requests/responses and need to extract at run time, unable to understand how to achieve.
Tried Regular Extractor choosing URL radio button, but it captures the value from recorded script.
Steps followed:
Record script using Blazmeter (Browse URL xx.com>Click Login)
Redirected to URL(s) in which one of the url has "code_Challenge" parameter with run time value)
First URL is: accounts-xx.com/oauth2/oidcdiscovery/.well-known/openid-configuration> The response doesn't have any parameter values
Second URL is:
https://accounts-xx.com/oauth2/authorize?response_type=code&client_id=zzzz&scope=ituytutut&redirect_uri=xx.com/callBack&code_challenge_method=ooo&**code_challenge=dsfsdlfhl**
In above 3rd point url, Code_challenge value is generated at run time when executed steps from browser.
However If replayed the recorded script which would have already generated code value hence other requests would fail. Due to this, need to get the code value fetched.
The code_challenge is generated from WS02 service.
Jmeter version: 5.3
Please suggest, or should we need to use Selenium webdriver integration.
Regular expression which would extract the value from recorded script:
As per Mitigating Authorization Code Interception Attacks article:
code_challenge The client creates and records a secret cryptographically random string (the code_verifier), which is then encoded using URL safe base64 encoding to transform it into the code_challenge.
As per PKCE in WSO2 IS server article:
1.Plain:
If a code_challenge method is mention as plain or not mention at all it will take this plain value. Then code_challenge will like:
code_challenge = code_verifier
2. SHA256:
To have the code_challenge as SHA256, we should mention this in request otherwise plain value will be assumed.For SHA256 code challenge will be like
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
Here base64url is same as base64encoding(used so that all machine can identify as same value) but trailing “=” will be removed and “+” & “/” are placed by “-” & “_” to avoid unnecessary length in URL.(otherwise ‘+’ becomes ‘%2B’, ‘/’ becomes ‘%2F’ and ‘=’ becomes ‘%3D in URL)
As much as possible, it is better to select the code challenge method as SHA256 then the flow will become more secure and hard to guess(if someone try to brute force it)
So I think you need to add JSR223 PreProcessor and calculate/generate the code_challenge using the algorithm used by your server in Groovy language, store the value into a JMeter Variable and use it in the request.
You can leave the field value empty and then its value gets updated once the request is sent. But you won't see the value in the request.
I had a similar issue, it worked in my case.

Jmeter is converting '#' in the Password into junk character

I am recording Login in Jmeter. Password has '#'. Jmeter recorded exact string but when i run the same, '#' is converted to '%40ss' and login is getting failed(login is failing even if i pass parameters through csv file). But if we pass parameters through jmeter Body Data, Login is successful. I dont want to pass through Body Data, i want to send parameters through CSV file. How to achieve this. Please find the attachments
Recorded and Response
My expectation is that it is only a matter of representation, i.e. when I run similar request using a sniffer tool like Wireshark I can see # sign as a part of form data.
Most probably your problem lies somewhere else, i.e. you haven't correlated this __RequestVerificationToken or haven't added HTTP Cookie Manager.
When it comes to load testing ASP.NET web applications you cannot just record and replay your test, you need to perform correlation of dynamic parameters, check out ASP.NET Login Testing with JMeter article for more details.
Lakshmikanth, when you are passing any special character in parameters values then JMeter converts that character into percent-encoding for eg. '#' converts to '%40', '!' converts to '%21'.
To overcome this issue you can pass your password as it is [say P#ssword] in the .csv file but in your request you need to uncheck the encode checkbox corresponding to your password parameter.

Passing whole body as a variable to a POST request

I'm trying to create a simple stress test using JMeter. I have mostly GET requests and a couple POST requests. My main goal is to make this test as reusable as possible. I want to implement it in a way that the user would have to provide a CSV file with the following headers:
method;path;postBody
The values would look something like:
GET;/path/to/resource;''
POST;/path/to/resource;'{"key":"value","key":"value","key":"value"}'
Now POST (PUT, PATCH etc ..) bodies differ from one request to another. Providing ${postBody} to Body Data tab does not work "${postBody}" as well.
Is there a way to achieve this? Command line solutions are more than welcome as well.
EDIT: To clarify, I'm using the UI interface. When I input ${postBody} in the Body Data tab the UI complains. When switching from the Body Data tab to another one I get the following prompt:
Remove "'" around the request and it should work.
Regarding the warning you get, it is not an error, it is just that in JMeter those 2 tabs are exclusive:
Parameters tabs is for input of parameters in the form as name=value
Body data is for your kind of requirement
So can you test my hypothesis which is to remove the quote around the request in CSV file ?
If it still fails, please show the logs.
You can remain in Body Data tab,
Add after pathPost your optional query parameters for GET request:
${pathPost}?${getPramaters}
Don't worry about the ? it's just seperate path from parameters
Also consider changing variable name to path, more suitable because it can be POST.
In JSON , seperate between values while in CSV default is also ,
I suggest you can your CSV delimiter, In CSV Data Set Config Choose different Delimiter as ; and add your data in CSV accordingly (remove extra ' characters):
POST;/path/to/resource;{"key":"value","key":"value","key":"value"}
Notice: Allow quoted data keep default value False

JMeter not attaching contents of binary file to POST data in HTTP Request

I'm attempting to simulate a login call with JMeter 2.11 to a service that uses a binary format. I've created an Http Request with the appropriate settings, except for the body data. I need to POST raw binary data.
According to the docs here, I should be able to set the file path for exactly one file, with no parameter name, and no other content in the Body Data, and have it place the data in the request body.
If it is a POST or PUT or PATCH request and there is a single file whose 'Parameter name' attribute (below) is omitted, then the file is sent as the entire body of the request, i.e. no wrappers are added. This allows arbitrary bodies to be sent. This functionality is present for POST requests after version 2.2, and also for PUT requests after version 2.3.
However, when I run the test, the POST Data is empty.
I have tried the extra set of plugins for JMeter as well, but alas, I'm stuck. The loaded file has 145 bytes of data, and the request shows that the content-length is 0. What am I missing?
The Http Request
The result
Update 1
To clarify, I am NOT attempting to send a file, I'm attempting to send a binary encoded message as raw POST data.
Switch back to Parameters tab not Post body.
See:
http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Request
Yoy could try recoring to see how the resuest look like.
This is my solution,maybe not best, but it works fine:
1st step :
You should write your binary data to a file (assume it's name is
FILENAME);
2nd step :
For your http request sampler,Yout should put ${FILENAME} under file
path in the "Send Files with the request" section (while leaving its
paramter name empty and specifying an encoding (for binary, it is
application/binary)).
Hope it helps.
Refer to this article

How do I calculate the content-length of a file upload in ruby?

I need to include the content-length of a image /png file posted in an upload to a webservice.
But how do I calculate the content-length to include in the header?
Thanks.
I am submitting it using rest-client.
The webservice for the upload is Postful: and the documentation has been unclear: http://www.postful.com/developer/guide#uploading_attachments
Because I am writing the payload and headers, seems like I need to input that value.
I am also looking at postalmethods which says that the content-length is the user input:
http://postalmethods.com/method/2009-02-26/UploadFile
The files themselves are .PNG. I am going to attach them to a model using Paperclip, so will have a filepath from that.
The file that I need the content-length to post is stored as an attachment using paperclip, so the specific code generating problems is:
File.size(#postalcard.postalimage.url)
Well, you know how you're reading and posting the data, presumably - so you know how much data you're sending. That's the content length. If you're just sending it directly in binary as the body of the post, it's just the length of the file. If you're base-64 encoding it, then the content length will be the ((file length + 2) / 3) * 4. If it's going in a SOAP envelope etc, you'll need to take account of that.
One way of doing this for complicated situations is to build the entire post body in memory first, set the content length, and then just copy from memory directly to the post body.
Well, you can use File.size(filepath) but it's unlikely that you'll need to - most libraries for making HTTP requests should do that automatically - which library are you using? (Or, what kind of webservice is it?)

Resources