Use script to form request body in IntelliJ integrated http client - http

In pseudo-whish-language this is what I try to achieve in IntelliJ integrated http client:
POST {{basepath}}/upload
Content-Type: application/json
{
"content": "{% btoa(await fetch('my-file.dat')) %}"
}
Normally, one would use the following to upload a file raw or as part of a multipart request:
< my-file.dat
But in my case, the binary file has to be encapsulated in a json and encoded using base64. I tried putting the file into a variable, but I can't find a way to run a script (for setting the variable) before the request is sent and also it doesn't seem possible to use script directly as part of the request. And I'm also not sure if I'm able to access external files from the script.
I cannot send it as multipart as proposed in Add file to multipart form request in IntelliJ HTTP Client because my server doesn't accept non-json requests.
Do I have any other options or is this a missing feature of this http client?

I did some tricks to achieve something similar.
I created an Environment Variable with the data parsed to base64 format.
{
"dev": {
"png_image_base64": "--your format data in bae64--"
}
}
Then, I added this as a reference in my HTTP request.
### ADD FILE TO TRACKING
POST http://localhost/files
Content-Type: application/json
Authorization: Bearer {{personal_access_token}}
{
"file": "{{png_image_base64}}"
}
Finally, run the request with the dev environment.
You could create many vars with different files of content: pdf_base64, png_bas464, etc. depending on your necessities. The "bad thing" is that you need to parse manually each of these files, but only once, after that, you could use it on a json and perform many tests.
I hope that it could be useful for someone.
Regards.

Related

Is there a way to set the http Header values for an esp_https_ota call?

I'm trying to download a firmware.bin file that is produced in a private Github repository. I have the code that is finding the right asset url to download the file and per Github instructions the accept header needs to be set to accept: application/octet-stream in order to get the binary file. I'm only getting JSON in response. If I run the same request through postman I'm getting a binary file as the body. I've tried downloading it using HTTPClient and I get the same JSON request. It seems the headers aren't being set as requested to tell Github to send the binary content as I'm just getting JSON. As for the ArduinoOTA abstraction, I can't see how to even try to set headers and in digging into the esp_https_ota functions and http_client functions there doesn't appear to be a way to set headers for any of these higher level abstractions because the http_config object has no place for headers as far as I can tell. I might file a feature request to allow for this, but am new to this programming area and want to check to see if I'm missing something first.
Code returns JSON, not binary. URL is github rest api url to the asset (works in postman)
HTTPClient http2;
http2.setAuthorization(githubname,githubpass);
http2.addHeader("Authorization","token MYTOKEN");
http2.addHeader("accept","application/octet-stream");
http2.begin( firmwareURL, GHAPI_CERT); //Specify the URL and certificate
With the ESP IDF HTTP client you can add headers to an initialized HTTP client using function esp_http_client_set_header().
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_http_client_set_header(client, "HeaderKey", "HeaderValue");
err = esp_http_client_perform(client);
If using the HTTPS OTA API, you can register for a callback which gives you a handle to the underlying HTTP client. You can then do the exact same as in above example.

Binary data in body is corrupted when sending HTTP POST in JMeter

I have a local web app with an HTTP POST endpoint.
This endpoint receives emails sent from SendGrid.
I have saved the body of a previous email with attachments which I know works, as requestBody.bin.
I'm trying to replicate this HTTP POST request using JMeter.
I have this Beanshell Preprocessor script:
FileInputStream in = new FileInputStream("C:\\Projects\\centaurjmeter\\src\\InboundEmails\\requestBody.bin");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[999024]; //Value of Content-Length from when I sent the actual email. So this should be more than enough just for the HTTP POST body.
for (int i; (i = in.read(buffer)) != -1; ) {
bos.write(buffer, 0, i);
}
in.close();
byte[] requestBody = bos.toByteArray();
bos.close();
vars.put("requestBody", new String(requestBody, "ISO-8859-1"));
and I'm using ${requestBody} in the body of the HTTP POST request:
This is what my JMeter test looks like:
In my HTTP POST action method, I'm saving the attachments of the email to file.
The pdfs seem to be slightly corrupted, only part of the text on each page is showing.
The .png files do not even open.
I've tried using:
vars.put("requestBody", new String(requestBody));
vars.put("requestBody", new String(requestBody, "Windows-1252")); //ANSI
vars.put("requestBody", new String(requestBody, "ISO-8859-1")); //default encoding
But none of them work. "ISO-8859-1" results in the least amount of corruption, in that at least some text appears in the pdfs (but the .png files don't work at all).
I can't use a HTTP Raw Request Sampler because that doesn't work with https.
How can I get the bytes from requestBody.bin and send them in my HTTP POST body correctly?
UPDATE
I read https://stackoverflow.com/a/41892324/2063755 and tried sending requestBody.bin as a file with the request in the "Files Upload" tab, but I get the same result as using the Beanshell Preprocessor script.
UPDATE
The above link actually did help me solve the problem.
I just had to add this extra TE header:
You need to ensure that the same encoding is being applied everywhere, I would recommend sticking to UTF-8
Run JMeter providing file.encoding=UTF-8 property, it can be added to system.properties file (lives in "bin" folder of your JMeter installation)
Since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting so you can use the following __groovy() function directly in the "Body Data" tab of your HTTP Request sampler:
${__groovy(new File('C:\\Projects\\centaurjmeter\\src\\InboundEmails\\requestBody.bin').getText('UTF-8'),)}
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It
Assuming everything goes well your "local web app" should see the identical file, it can be double-checked using a 3rd-party sniffer tool like Wireshark. Make sure to use UTF-8 for parsing the file in your app as well.

How does Postman send a file via HTTP?

I am really curious about how Postman sends a file via multipart/form-data HTTP request type.
I'm unable to track the algorithm that is used to compress the file, it won't show the complete request when trying to get the request code.
I'm interested in JavaScript/React (fetch) approach.
Any idea?
Thanks
It creates new FormData instance and appends upload as key and full path /home/light/Downloads/helixnebula.jpg to it as a value. Postman UI:

Symfony 4 & Postman access File from post-data POST request

I'm trying to do an image upload using a Symfony REST API.
However, I'm having problems trying to read the POST request file parameter on Symfony's side using Postman.
On Postman I have the following body on the POST request:
form-data POST request with key=file and value=some image
When the Request reaches Symfony, I have the following:
public function uploadImage(Request $request)
{
$params = $request->request;
$file = $params->get('image');
dump($file);
...
}
The file variable is null. I have also tried using $params = $request->files but the result is the same.
If I dump $request->getContent() I can see the file is passing through, but cannot have access to it to do what I need.
Am I missing something?
I managed to figure it out, it has something to do with the Postman app I'm using.
Basically, when I choose form-data on the body, the Headers tab is not automatically updated to something like Content-Type => multipart/form-data, it just keeps the previous one it existed (application/json, for example).
When I found this out, I changed the Content-Type to multipart/form-data but it was still not working.
It only worked when I unticked the Content-Type on Headers.
Why is that?
I was missing the boundary part on the Content-Type, which Postman automatically generates when the body is a form-data and no Content-Type header is generated.
So,
Content-Type = multipart/form-data -> doesn't work
Content-Type = multipart/form-data; boundary=----WebKitFormBoundary5Qa5cbeHtIOCMAKa -> works fine (you don't need to specify this, as Postman will make a request with this set)
I think what you should use is $request->files->get('file');

Is there a REST API I can use to test a simple client script? Not a test client for a REST API

I'm not looking for a tool to test a REST API, I'm looking to find a REST API that I can send simple GET or POST request to test out a very simple client script that I have.
So my question would be is there one out there that I can use? I need to collect some data for my report. Thanks.
There are lots, but REST is a very open world, for instance, technically calling any url via GET is executing a REST service.
If you know which type of service (RESTier,OData...) or what format you would like the response in (XML, JSON...) or even what topic of content you intend on targeting, we can probably provide better examples, but lets start small:
GET: bot.whatismyipaddress.com
This service simply returns your public IP address in plain text.
If you are interested in JSON responses, try something like: (http://www.jsontest.com)
GET: http://ip.jsontest.com/
This will return a JSON object similar to this:
{"ip": "8.8.8.8"}
If you are more interested in testing how you can POST or send a JSON packet to a service, then try something like this: (http://jsonplaceholder.typicode.com)
POST /posts HTTP/1.1
Host: jsonplaceholder.typicode.com
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 89bda029-e321-f132-1b52-aab9d4b2841f
{ "test":"one" }
returns the following:
{
"test": "one",
"id": 101
}
Good Luck!

Resources