Getting Jmeter to generate the boundary dashes in the Content-Type header (eg boundary=--V0a4bfux...) - jmeter

This what my HTTP request is generating
Content-Type: multipart/form-data; boundary=V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp; charset=UTF-8
However, when compared to the POST data, it is lacking the 2 dashes in the front, which causes the server to reject the request:
--V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp
Content-Disposition: form-data; data="dataToBeSent"
--V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp--
How do I get Jmeter to generate the dashes in the header?
(besides from manually creating the multipart form)
Note:
I am using the 'Use multipart/formdata for POST' option.
If I intercept the request and manually add the dashes in the header, the
server accepts the request.

You don't need to generate these values, the solution is to tick Use multipart/form-data for POST box in the HTTP Request sampler (or in the HTTP Request Defaults)
If you have any definition of Content-Type header in the HTTP Header Manager - you need to remove it and let JMeter generate appropriate Content-Type header on its own.

The header doesn't need the dashes. This is simply how multipart/form-data works. The body is built as follows:
--<boundary>
<headers>
<content>
--<boundary>
<headers>
<content>
--<boundary>--
The -- part indicates a new part starts. The body ends with ---- to indicate no new parts will follow.

Related

POST a JSON and a CSV in a multipart/form-data request through a NiFi 1.15 InvokeHTTP processor

I'm working on a NiFi 1.15 flow where I have to send a request to a service that requires 2 pieces of form-data sent in a POST request as a multipart/form-data. The first part is a simple JSON object with a few parameters, while the second part is a CSV file. Here is an example of what I am trying to achieve.
Content-Type: multipart/form-data; boundary=1cf28ed799fe4325b8cd0637a67dc612
--1cf28ed799fe4325b8cd0637a67dc612
Content-Disposition: form-data; name="json"; filename="json"
{"Param1": "Value1","Param2": "Value2","Param3": true}
--1cf28ed799fe4325b8cd0637a67dc612
Content-Disposition: form-data; name="file"; filename="body.csv"
Field1,Field2,Field3,Field4,Field5
VALUE_FIELD_1,VALUE_FIELD_2,VALUE_FIELD_3,"Some value for field 4",VALUE_FIELD_5
--1cf28ed799fe4325b8cd0637a67dc612--
Another acceptable output would have the Content-Disposition lines empty.
Due to a few restrictions in the environment I am working on, I am not allowed to use scripting processors, such as ExecuteGroovyScript as suggested in another SO question.
Instead, I started creating a GenerateFlowFile -> InvokeHTTP flow. The GenerateFlowFile would output to a flow file a text similar to the one mentioned above. Here is the screenshot of the GenerateFlowFile.
The connected InvokeHTTP processor is configured to use the POST Http Method and to send headers (the Authorization header in my case) and Send Message Body is set to true. It also extracts the Content-Type from the flow file previsously generated attribute through a ${mime.type} function. You can see the details in the following screenshots.
Sadly, this does not work. The server responds with an "Unexpected end of MIME multipart stream. MIME multipart message is not complete." error.
After searching for a while in SO, I found another question describing what looks like a similar problem, but there they are getting a different error and is also posting parameters through a different method.
I am also aware about the blog post from Otto Fowler where he shows how InvokeHTTP supports POSTs with multipart/form-data. I did try this approach too, but did not manage to get it working. The service throws an error stating that NiFi does not send one of my post:form:parts.
Right now I am stuck and am not able to send that data. I did manage to write a simple Python script to test if the server is working properly and it is. For reference, here is the script:
import requests
server = 'https://targetserver.com'
#Authentication
result = requests.post(server + '/authentication',
{'grant_type': 'password',
'username': 'username',
'password': 'password'})
token = result.json()['access_token']
#Build the request
headers = {'Authorization': 'bearer ' + token}
json_data = '{"Param1": "Value1","Param2": "Value2","Param3": true}'
# First the JSON then the csv file.
files = {'json': json_data,
'file': open('body.csv', 'rb')}
result = requests.post(server + '/endpoint', headers = headers, files = files)
print(result.text)
Does anyone have a suggestion on how to get around this situation?

Nifi/Minifi: How to read multipart/form-data request

I'm using HandleHttpRequest processor to receive a request with Content-Type: multipart/form-data. The request contains a text param and a file (Content-Type: image/jpeg). How can I read this parameters, and put them into attributes?

Jmeter parameterization for content of the file uploaded

I'm trying to parameterize content of the file uploaded through CSV Data Set Config
But file not picking the variables values ( can see the data of csv file in request but the uploaded file not updated with the number) Showing the request like this
**
POST data:
--3TJ-KduX0_gdJ3BvxwP97-p3PBN0Jki-2P7Iyvd
Content-Disposition: form-data; name="SO"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
403331689
--3TJ-KduX0_gdJ3BvxwP97-p3PBN0Jki-2P7Iyvd
Content-Disposition: form-data; name="sourceFile"; filename="SO_perf_test_porfornmance.xml"
Content-Type: text/xml
Content-Transfer-Encoding: binary
**
If you're sending the file via "Files Upload" tab of the HTTP Request sampler like this:
JMeter doesn't evaluate any Functions or Variables which are inside the file, it sends the file "as it is".
One of the solutions would be using a temporary file like SO_perf_test_porfornmance_modified.xml in the HTTP Request sampler and the content of this file can be modified "on-the-fly" using JSR223 PreProcessor like:
Add JSR223 PreProcessor as a child of the HTTP Request sampler which uploads tile
Put the following expression into "Parameters" section:
${__eval(${__FileToString(SO_perf_test_porfornmance.xml,,)})}
where:
__FileToString() function reads the content of the SO_perf_test_porfornmance.xml into memory
__eval() function resolves all the functions and variables in it
Check out Here’s What to Do to Combine Multiple JMeter Variables article if you need more detailed explanation.
Put the following code into "Script" area:
new File('SO_perf_test_porfornmance_modified.xml').text = Parameters
Configure your HTTP Request sampler to send SO_perf_test_porfornmance_modified.xml file instead of the SO_perf_test_porfornmance.xml
That's it, JMeter will now be sending the new file which contains all the nested functions and/or variables resolved to their respective values

JMeter Multipart JSON Request Form Data

I am trying to construct a HTTP Request through JMeter that uses a multipart data body.
I have a HTTP Header Manager that has COntent-Type set to multipart/form-data; boundary=AaB03x. I selected 'Use multipart/form-data for POST'.
I then have a data body created as,
`-----------------------------AaB03x
Content-Type: application/json
Content-Disposition: form-data; name="part1"
{"jsonKey1": "JsonValue1" }
-----------------------------AaB03x
Content-Type: application/json
Content-Disposition: form-data; name="part2"
{
"jsonKey2": "JsonValue2"
}
-----------------------------AaB03x
Content-Type: application/octet-stream
Content-Disposition: form-data; name="part3"
File Content here!!!!
-----------------------------AaB03x`
When I run this, I see that the request doesnt send the body correctly, instead it just sends some random data as,
POST data:
--vKOghkU7riRQbaANmmGpMs7j9TxCTUp3S2T0vE--
And gives an error response of,
`{"errorMsg":"Unable read headers from MultipartStream.","messageCode":"UnableReadHeadersFromMultipartStream","httpStat us":"BAD_REQUEST","requestName":"RequestName"}`
My second question is:
the part3 of the request sends a file to upload. Can I pass the file path somehow?
Given you set your own boundary and build your request manually I believe you need to uncheck Use multipart/form-data for POST in the HTTP Request Sampler
If your file encoding isn't very "exotic" you can try using __FileToString() function just instead of File Content here!!!!.
Looking into RFC 7578, it seems you also need a trailing -- at the end of the last line
You should try sending your JSON data as parameters. Also put your file path in the section for that... And even some servers don't actually need MIME type explicitly declared, you can check yours with some online tool like this one.
Your HTTP Request could look smethnig like:

How to retrieve XML into Oracle PL/SQL via an HTTP Post transaction?

I'm trying to implement the "blog this" function from Flickr using the BloggerAPI to my pl/sql based CMS.
When Flickr sends me the posting transaction, the HTTP transaction looks like this:
POST /pls/website/!pkg.procAPI HTTP/1.1
Host: www.mydomain.com
Accept: */*
User-Agent: Flickr
Content-Type: text/xml; charset=utf-8
Content-Length: 1220
Expect: 100-continue
<?xml version="1.0" encoding="utf-8"?>
<methodCall>
<methodName>blogger.newPost</methodName>
<params>
<param><value><string>NO_APP_KEY</string></value></param>
<param><value><string>1</string></value></param>
<param><value><string>markj</string></value></param>
<param><value><string>markj</string></value></param>
<param><value><string>This is a test post from <a href="http://www.flickr.com/r/testpost"><img alt="flickr" src="http://www.flickr.com/images/flickr_logo_blog.gif" width="41" height="18" border="0" align="absmiddle" /></a>, a fancy photo sharing thing.</string></value></param>
<param><value><boolean>1</boolean></value></param>
</params>
</methodCall>
But my server is responding with an HTTP-400 Bad Request and the error message is "Signature Mismatch or Missing '='" and my pl/sql procedure never gets a chance to process the request. I suspect that the flexible parameter passing is getting hosed when looking at the message, but I don't know how else
The process to get the available blogs seems to work ok, but the content of the request doesn't have all the html entities as part of the message:
POST /pls/website/!pkg.procAPI HTTP/1.1
Host: www.mydomain.com
Accept: */*
User-Agent: Flickr
Content-Type: text/xml; charset=utf-8
Content-Length: 304
<?xml version="1.0" encoding="utf-8"?>
<methodCall>
<methodName>blogger.getUsersBlogs</methodName>
<params>
<param><value><string>NO-APP-KEY</string></value></param>
<param><value><string>mark</string></value></param>
<param><value><string>markj</string></value></param>
</params>
</methodCall>
Is there a way to get the xml data from the body of the http request directly? or some other approach I'm over looking?
Thanks,
Mark.
I opened a service request with Oracle and they confirmed that mod_plsql does not support retrieving httpheader variables. Here is the discussion I had on the SR:
ISSUE ANALYSIS
I need to confirm it, but Mark conclusion so far looks right to me,i.e. MOD_PLSQL is always invoking and processing PLSQL procedures and there is no way to read the raw HTTP request because MOD_PLSQL parses the request and checks if there is a PLSQL procedure with this name and if there are arguments to pass. If there are no arguments to pass but we are providing something else like the XML document, MODPLSQL gets puzzled and thinks this is a new pair of parameter and value when this is not really the case.
ANSWER
No, it is not possible to do it because MOD_PLSQL just treats requests with parameters which can be parsed and translated as a PLSQL procedure call with several arguments. MOD_PLSQL has no concept of a "httprequest" variable containing the whole request in the same way java has the HTTPRequest object
ISSUE ANALYSIS
Got the confirmation unless we pass it as a parameter we can not read it from MOD_PLSQL. In other words, if we pass the XML page in the HTTP request body we need to use something like java where we can treat the request in raw mode and we can read any HTTP header and the http body without restrictions of any kind.
Can the xml be sent as a file attachment? In other words change:
Content-Type: text/xml; charset=utf-8
to
Content-Type: multipart/form-data, boundary=AaB03x
Then add this before the xml:
--AaB03x
content-disposition: form-data; name="xmlfile"; filename="myfile.xml"
Content-Type: text/xml
And this after the xml:
--AaB03x--
Now, you set up the procedure for a file upload, as explained in this article:
Files, Uploads, and Downloads with Web PLSQL
Use UTL_HTTP
You can use the UTL_HTTP package to do this.
UTL_HTTP.read_text(
r IN OUT NOCOPY resp,
data OUT NOCOPY VARCHAR2,
len IN PLS_INTEGER DEFAULT NULL);
"The UTL_HTTP package supports HTTP 1.1 chunked transfer-encoding. When the response body is returned in chunked transfer-encoding format as indicated in the response header, the package automatically decodes the chunks and returns the response body in de-chunked format."
http://download.oracle.com/docs/cd/B10500_01/appdev.920/a96612/u_http.htm
I'm encountering the same issue MojoMark was (though with a different external application). MojoMark's follow up comment is correct, the read_text information does not answer the question.
Like MojoMark, I am attempting to RECEIVE a POST from an external entity. The PLSQL I'm trying to write is to receive that POST and store it.
I was able to write the outbound POST XML with no problem, but have been unable to set up a procedure to receive it.
The issue appears to be the PLSQL procedure wants a variable name, ie:
http://server/modplsql/testload, POST "data='data'"
However, the body of the POST is just an XML data stream, no "=" assigning a value to a parameter, so the function gets the "Mismatch or Missing '='"" error.
It seems like there should be a way to tell MODPLSQL to just accept accept the post data like a "typical" function call, but I think I'm missing something obvious.
The basics function I'm trying to use to receive the post is:
procedure testload ( DATA in clob ) as
BEGIN
htp.print('Input POST stream was ' || DATA )
end testload;
The only significant difference I can see between the two requests is the "Expect: 100-continue" business. This appers to be a clause in the HTTP 1.1 specification which allows the client to split the request in two. Basically, the client sends the header to the server, and the server must make a choice. If it is "happy" with the header it will give a HTTP 100 response to indicate that the rest of the message will be accepted.
Since you're getting data from Flickr, I'm not sure what level of control you have over the http requests being made by the client. From the server side it may be necessary to make a configuration change to Apache, or it may be a bug in mod_plsql that's popping up with the "!" flexible parameter marker.
Either way, the current blogger api is not like this. You probably should move to the new GData API.

Resources