Gzipped soap request in Jmeter - soap

Is it possible to send a gzipped soap request?
I added an HTTP Header Manager with the following headers:
Content-Type: application/soap+xml; charset=Utf-8
Content-Encoding: gzip
I added a Beanshell PreProcessor as a child of the request which needs to be encoded, and I defined the following script:
import org.apache.commons.io.IOUtils;
import java.util.zip.GZIPOutputStream;
// This only works for the HTTP Request, not Soap Request.
// String bodyString = sampler.getArguments().getArgument(0).getValue();
String bodyString = ctx.getCurrentSampler().getXmlData();
byte [] requestBody = bodyString.getBytes();
ByteArrayOutputStream out = new ByteArrayOutputStream(requestBody.length);
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(requestBody);
gzip.close();
// This only works for the HTTP Request, not Soap Request.
// sampler.getArguments().getArgument(0).setValue(out.toString(0));
ctx.getCurrentSampler().setXmlData(???);
My problem is the last line, how can I set xmlData?
Jmeter version 3.1

Replace SOAP/XML-RPC Sampler which is deprecated with the HTTP Request sampler
Upgrade to JMeter 5.0 (or whatever is the latest version available at JMeter Downloads page)
Switch from Beanshell to Groovy
Use sampler.getArguments().getArgument(0).setValue(out.toString(0)); in order to generate the request body.

Related

How do I POST a JSON body AND a Video file to an API endpoint on JMeter?

I'm unable to send both, JSON body data and a video/image file together in one request on JMeter. It gives a 401 unauthorized, even though I have added the Authorization header in the HTTP Header Manager. The same request with headers works fine on Postman.
I've already referred to this guide here with no luck.
https://www.blazemeter.com/blog/testing-advanced-rest-api-file-uploads-jmeter/
Content-Type: multipart/form-data
{
"email": "xyz#gmail.com",
"password": "xyz",
"file": ${__FileToString("/Downloads/SampleVideo_1280x720_1mb.mp4")}
}
SAMPLER RESULT:
Thread Name: Thread Group 1-1
Sample Start: 2019-09-30 14:26:25 IST
Load time: 2922
Connect Time: 838
Latency: 2922
Size in bytes: 202
Sent bytes:1056397
Headers size in bytes: 202
Body size in bytes: 0
Sample Count: 1
Error Count: 1
Data type ("text"|"bin"|""):
Response code: 401
Response message: Unauthorized
HTTPSampleResult fields:
ContentType:
DataEncoding: null
REQUEST:
POST data:
--o3F8APyqP080W3wk0N_-96jzl11Bfsa
Content-Disposition: form-data; name="file"; filename="SampleVideo_1280x720_1mb.mp4"
Content-Type: video/mp4
Content-Transfer-Encoding: binary
<actual file content, not shown here>
--o3F8APyqP080W3wk0N_-96jzl11Bfsa--
[no cookies]
JMeter should be doing what real browser (or other application using your API endpoint) is doing.
If the browser (or the application) sends 2 requests - JMeter must be sending 2 requests as well. If the browser (or the application) sends 1 request - JMeter must be sending 1 request. In case of 1 request my expectation is that you should be sending application/json as the value of the Content-Type header like it's done in the guide you're referring.
--boundary
Content-Type: application/json; charset=UTF-8
JSON Metadata
--boundary
Content-Type: file MIME type
File content
--boundary--
The answer is quite simple: just record the request using JMeter's HTTP(S) Test Script Recorder and JMeter will come up with proper configuration of the HTTP Request sampler(s), HTTP Header Manager, etc. All you will need to do is to implement parameterization and correlation so the script could be replayed successfully.
One important bit: during the recording you need to have SampleVideo_1280x720_1mb.mp4 file in JMeter's "bin" folder as modern browsers don't return the full path hence JMeter will be able to properly capture the file upload request only if the file lives in its "bin" folder. More information: Recording File Uploads with JMeter
To post json body and attachment you can add your "email" and "password" in Parameters tab of JMeter HTTPS request and file in Files Upload tab.

JAX WS generated client gets "Unable to determine SOAP version" from new Axis2 versions

We have SOAP Web Service running on Axis2-server. On client side we use JAX WS generated client. We tried to updgrade our Axis2-server from 1.6.2 to 1.7.7 and found that JAX WS client doesn't work anymore. Server returns "Unable to determine SOAP version" from Axis2-server. I searched that "Unable to determine SOAP version" error is coming from axiom library which reads type parameter from Content-Type of SOAP message.
Example of SOAP request headers:
Accept: application/soap+xml, multipart/related
Content-Type: multipart/related;start="<rootpart*897f69f7-8c00-461b-a0c3-08d07ea4e433#example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:897f69f7-8c00-461b-a0c3-08d07ea4e433";start-info="application/soap+xml;action=\"Authenticate\""
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
--uuid:897f69f7-8c00-461b-a0c3-08d07ea4e433
Content-Id: <rootpart*897f69f7-8c00-461b-a0c3-08d07ea4e433#example.jaxws.sun.com>
Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml;action=\"Authenticate\""
Content-Transfer-Encoding: binary
This is in fact a bug in Apache Axiom; see AXIOM-492.

Getting 400-BAD REQUEST when trying to upload diff to ReviewBoard using api

I have created a review request on ReviewBoard using the api, but I am now unable to add a diff file to this review request.
I am following the ReviewBoard instructions to sent a POST request to ReviewBoard API --> https://www.reviewboard.org/docs/manual/2.0/webapi/2.0/resources/diff-list/
My request header looks like this
{Content-Type: multipart/form-data; boundary=------- 1511347017267}{Accept: application/xml}{Authorization: token 4937d...sometoken...584b23}
My request body looks like this
------- 1511345733192
Content-Disposition: form-data; name="basedir"
/trunk_projectABC/
------- 1511345733192
Content-Disposition: form-data; name="path"; filename="build.diff"
Content-Type: text/xml
Index: utility/build.bat
===================================================================
--- utility/build.bat (revision 67210)
+++ utility/build.bat (working copy)
## -10,8 +10,8 ##
echo off
set thpcra=false
set patchBuild=false
-set help=true
-set clientBuild=true
+set help=false
+set clientBuild=false
set runJavaTestCases=false
set buildpath="%BUILD_PATH%"
set jdkpath="%JDK_17%"
------- 1511345733192 --
I found another question here
review board diff not uploading
and made sure that the repo URL + basedir + relative path is set right but I still get BAD REQUEST response from the server.
NOTE: I generated the diff using tortoiseSVN tool
I am using HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Any inputs on why I am getting BAD REQUEST from the server ?
Answering my own question.
I was using PrintWriter to write the request body on the connection output stream. Probably using a stream introduced any extra characters or somehow malformed the request body, but it was the reason why I was getting bad request.
I am now using MultipartRequestEntity to create the request body. Here is the code snippet
PostMethod method = new PostMethod(apiURL);
File diff = new File("D:/path_to_diff/build.diff");
partsList.add(new FilePart("path", diff.getName(), diff));
partsList.add(new StringPart("basedir", "/trunk_projectABC/"));
Part[] parts = partsList.toArray(new Part[partsList.size()]);
RequestEntity entity = new MultipartRequestEntity(parts, method.getParams());
method.setRequestEntity(entity);
This works and uploads a diff file on the review request

How to upload an image using AWS API Gateway Proxy Integration with S3

After setting up my API to upload files, I realised that there is a special case where you want to upload a picture (jpg), you defined the binary support at the API, but you get the following error:
The request signature we calculated does not match the signature you
provided. Check your AWS Secret Access Key and signing method.
Consult the service documentation for details.
The Canonical String for this request should have been
'PUT /test/vi-dummy-bucket/testImg2.jpg
content-type:application/x-www-form-urlencoded
host:qhweyos7z2.execute-api.us-west-1.amazonaws.com
x-amz-date:20170808T154441Z
x-amz-security-token: // security token string no quotes
content-type;host;x-amz-date;x-amz-security-token 5fa90f0 ...'
The String-to-Sign should have been
'AWS4-HMAC-SHA256\n20170808T154441Z
20170808/us-west-1/execute-api/aws4_request
f7a38fa ...'
The strange thing is that uploading simple text files works with the exact same api call, then only thing I have to change is
Content-Type 'text/plain'
and write a text in the raw portion of the request.
Not sure if this is a Content-Type issue or a Request Body Issue, if I leave everything in the working state (text/plain & text in the body) and just change the body to binary and set the image, I get the above error.
My API gateway is in us-west-1 region
My S3 bucket is in us-east-1 region
And the request I am using is:
PUT /test/vi-dummy-bucket/testImg2.jpg HTTP/1.1
Host: qhwe7z2.execute-api.us-west-1.amazonaws.com
Content-Type: application/x-www-form-urlencoded
X-Amz-Security-Token: FQoDYX ...
X-Amz-Date: 20170808T154441Z
Authorization: AWS4-HMAC-SHA256
Credential=ASIAJICO6JFTJWN7A/20170808/us-west-1/execute-
api/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-
security-token,
Signature=6a792 ... Cache-Control: no-cache
Postman-Token: e9d1f730-f50b-7e27-70cc-c15a138d8cc6
(Binary Image)
This is another version of the request (same error):
PUT /test/vi-dummy-bucket/testImg2.jpg HTTP/1.1
Content-Type: image/jpeg
x-amz-security-token: FQoDY ...
x-amz-date: 20170808T190134Z
Authorization: AWS4-HMAC-SHA256
Credential=ASIAIZSP5YKVLJ3GVVQA/20170808/us-west-1/execute-
api/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-
security-token,
Signature=b2324 ...
Host: qhos7z2.execute-api.us-west-1.amazonaws.com
Connection: close
User-Agent: Paw/3.1.2 (Macintosh; OS X/10.12.6) GCDHTTPRequest
Content-Length: 823236
--- UPDATE ---
After implementing the sigV4 sigining manually using the generated SDK, the signature is no longer an issue.
The only problem left, is that the generated SDK only accepts a string as the "body", so I have to convert the file to a binary string. Then it passes correctly and a file is created in S3, but the size is now double and its not viewable, as if the binary string wasn't converted back to the binary file. So frustrating...
BTW, I've already tried PASSTHROUGH and CONVERT_TO_BINARY.
Updated: It looks like this may be related to a known error in Postman. For reference here is a related SO question: AWS Signature Error using Postman to access the AWS API Gateway when posting a binary
and here is the bug report for Postman: https://github.com/postmanlabs/postman-app-support/issues/3232
Does the request work if you use an alternate rest client and/or a command line utility like curl or httpie?
If you configured the binary support you should probably set the Content-Type to match the binary content you're sending.
From what you've posted you're sending the binary content with Content-Type application/x-www-form-urlencoded but if the body is actually a binary jpeg file I'd expect that you should be sending Content-Type image/jpeg

ReST: how can client tell server to return `Content-disposition: attachment`

So lets say I have a resource at /things.
If client does GET /things/myid I'll serve the default response (json).
If client passes an Accept: csv header I will serve the response as csv.
But what if I want to enable the client to tell the server to include a Content-disposition: attachment header in the response (to force a download)?