K6 how do i make a raw (non encoded) post - k6

I'm trying to use K6 to load test prometheus pushgateway and it wants posts in the following format.
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
there has to be a linefeed at the end of each line (and one extra at the end) - however I seem to only get url encoded strings like %20 for space etc. Is it possible somehow to post raw strings?

If you just construct the body as a string yourself and pass it that way to http.post(), it should be sent as-is, without any modifications. This code should illustrate this, using httpbin.org:
import http from "k6/http";
import crypto from "k6/crypto";
let payload = `http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
`;
export default function (data) {
console.log(crypto.sha256(payload, "hex"));
let resp = http.post("https://httpbin.org/anything", payload);
console.log(crypto.sha256(resp.json().data, "hex"));
console.log(resp.body);
}
it will output something like this:
INFO[0000] 773f0d81713fca0663ad7a01135bf674b93b0859854b2248368125af3f070d29
INFO[0001] 773f0d81713fca0663ad7a01135bf674b93b0859854b2248368125af3f070d29
INFO[0001] {
"args": {},
"data": "http_request_duration_seconds_bucket{le=\"0.05\"} 24054\nhttp_request_duration_seconds_bucket{le=\"0.1\"} 33444\nhttp_request_duration_seconds_bucket{le=\"0.2\"} 100392\n",
"files": {},
"form": {},
"headers": {
"Connection": "close",
"Content-Length": "161",
"Host": "httpbin.org",
"User-Agent": "k6/0.23.1 (https://k6.io/)"
},
"json": null,
"method": "POST",
"url": "https://httpbin.org/anything"
}

Related

The request body contains invalid JSON

I'm trying to POST to a discord webhook URL using Python Requests but whenever the embeds field is present, it returns {'code': 50109, 'message': 'The request body contains invalid JSON.'}. If I remove embeds and just leave content it will send without any errors.
My code is:
url = "https://discord.com/api/webhooks/[redacted]/[redacted]"
headers = {
"Content-Type": "application/json"
}
data = {
"username": "Webhook",
"content": "Hello, World!",
"embeds": [{
"title": "Hello, Embed!",
"description": "This is an embedded message."
}]
}
res = requests.post(url, headers=headers, data=data)
I've tried various version of the Discord API but the result is always the same.
I got it working by replacing
requests.post(url, headers=headers, data=data)
with
requests.post(url, json=data)
Try this. I think the requests library may be adding a header called content-type which conflicts with your header Content-Type, which makes the Discord API return an error:
url = "https://discord.com/api/webhooks/[redacted]/[redacted]"
headers = {
"content-type": "application/json"
}
data = {
"username": "Webhook",
"content": "Hello, World!",
"embeds": [{
"title": "Hello, Embed!",
"description": "This is an embedded message."
}]
}
res = requests.post(url, headers=headers, json=data)

API always error 408 - Invalid Data Type Sent

I really don't know what happen with this error (I mean by, is this related to the Flutter or Dart or the package that I used or the API that I used). In a nutshell, it always giving me back error code 408 - Invalid data type sent from my flutter App, while I COMPLETELY could done it in Postman and been tried it with PHP.
I just wanna call a normal POST request to my payment gateway API (I use Midtrans).
Here is my result:
From Postman
From my app in Flutter within VS Code
What am I doing wrong? I am completely has no clue about this.
I will give the detail below for anyone who want to try a simple call to this API so you can reproduce this.
Endpoint
https://api.sandbox.midtrans.com/v2/charge
Body
"payment_type": "bank_transfer",
"bank_transfer": {
"bank": "permata",
"va_number": "1234567890"
},
"transaction_details": {
"order_id": "order-101b-{{2020-11-0222rrd324dzz}}",
"gross_amount": 44000
},
"customer_details": {
"email": "richie.permana#gmail.com",
"first_name": "Richie",
"last_name": "Permana",
"phone": "+6281 1234 1234"
},
"item_details": [
{
"id": "item01",
"price": 21000,
"quantity": 1,
"name": "Schema Programmer"
},
{
"id": "item02",
"price": 23000,
"quantity": 1,
"name": "Ayam Xoxoxo"
}
]
}
This is the header
{
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
'cache-control': 'no-cache'
}
My Dart Function Snippet
Future _makePayment() async {
String url = "https://api.sandbox.midtrans.com/v2/charge";
final Map<String, String> header = {
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
'cache-control': 'no-cache'
};
var json = jsonEncode({
"payment_type": "bank_transfer",
"bank_transfer": {"bank": "permata", "va_number": "1234567890"},
"transaction_details": {
"order_id": "order-101b-{{2020-11-0222rrddzz557}}",
"gross_amount": 44000
},
"customer_details": {
"email": "richie#example.com",
"first_name": "Richie",
"last_name": "Permana",
"phone": "+6281 1234 1234"
},
"item_details": [
{
"id": "item01",
"price": 21000,
"quantity": 1,
"name": "Schema Programmer"
},
{"id": "item02", "price": 23000, "quantity": 1, "name": "Ayam Xoxoxo"}
]
});
Response response = await post(
url,
headers: header,
body: json,
);
var res = jsonDecode(response.body);
print(
"payloadddded =>> ${json.runtimeType}\n");
if (res['status_code'] == 201) {
print("ngeheeeee berhasil MIDTRAANSS =>> ${res['status_code']}");
} else {
print("res full =>> ${response.body}");
print("ape kaden => ${res['status_code']} || terosz => $res");
}
}
Note:
For the body, you may be need put more attention on the order_id because it will return some error if you not change the order_id (yes, think it like any other primary key id).
API Docs: https://api-docs.midtrans.com/
I really appreciate any helps or workaround given.
Thank you very much.
Dart's package:http manipulates the content-type header under the hood. If it does the encoding from string to bytes for you (i.e. if body is a string) then it adds a charset=xxx suffix to the content type - it becomes, for example application/json; charset=utf-8.
Apparently your server is allergic to this. (It shouldn't be, but whatever...). You can prove this using the dart:io http client.
var client = HttpClient();
var request = await client.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json; charset=utf-8');
request.headers.add(
'authorization',
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
);
request.add(utf8.encode(json));
var response2 = await request.close();
var reply = await response2.transform(utf8.decoder).join();
print(reply);
client.close();
This gives the same 408 error but does not if the charset suffix is removed.
There's a simple solution. Don't allow http to do the encoding for you - do it yourself.
var response = await http.post(
url,
headers: headers,
body: utf8.encode(json),
);
(Your json apparently needs work, because this now complains that the json is invalid, but that's easy to compare with your working postman.)

How to define pact-specification matching rule for single string body?

I am setting up a test for a put request uploading a file. The request body in my pact-file consists of a single string, containing a mime boundary that changes for every test run. I am trying to define a regex matching rule for the request body string, but it won't match. A similar matching rule for the header content-type does match.
How should I define the matching rule for the body if the body is only a string?
I'm using a reference implementation of Pact in Rust. The Pact-Specification version is 3.
"request": {
"headers": {
"Content-Length": "206",
"Host": "127.0.0.1:1234",
"Connection": "Close",
"Content-Type": "multipart/form-data; boundary=\"MIME_boundary_4FBA8D0826C707B6\""
},
"body": "--MIME_boundary_4FBA8D0826C707B6\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test_file.txt\"\r\nContent-Type: application/octet-stream\r\n\r\nContent of test file.\r\n--MIME_boundary_4FBA8D0826C707B6--\r\n",
"matchingRules": {
"header": {
"$.Content-Type": {
"matchers": [
{
"match": "regex",
"regex": "multipart/form-data; boundary=\"MIME_boundary_[A-Z0-9]{16}\""
}
]
}
},
"body": {
"$": {
"matchers": [
{
"match": "regex",
"regex": "--MIME_boundary_[A-Z0-9]{16}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test_file.txt\"\r\nContent-Type: application/octet-stream\r\n\r\nContent of test file.\r\n--MIME_boundary_[A-Z0-9]{16}--\r\n"
}
]
}
}
}
}
The code above is part of the pact file used in the test. The test results in a BodyMismatch error. Comparing the expected and received bodies shows that they only differ in mime boundary, so the regex matching is not working.
Through Pact's Slack channel we got the answer that the current Pact code does not support this type of matching. We created a feature request issue on GitHub:
https://github.com/pact-foundation/pact-reference/issues/43
The mime boundary value will always change. Writing a regular expression to match that will be quite challenging. It would be better to have a matching implementation that understands multi-part bodies. Pact-JVM supports this (see https://github.com/DiUS/pact-jvm/blob/master/consumer/pact-jvm-consumer-junit/src/test/groovy/au/com/dius/pact/consumer/junit/ExampleFileUploadSpec.groovy), so it would not be too hard to implement in Pact-Rust.

Can't convert successful Postman call to Ionic-Native HTTP.post [Ionic 2 ts]

I'm in the process of building an Ionic 2 (ts) app that will send a REST call to the OCR.space API. Going through their examples, I'm able to send a a Base64Image via HTTP.post, but when attempting to send a file via HTTP.Post, I'm met with:
{"ParsedResults":null,"OCRExitCode":0,"IsErroredOnProcessing":false,"ErrorMessage":["Parameter
name 'file' is invalid. Valid parameters:
apikey,url,language,isoverlayrequired,base64image"],"ErrorDetails":null,"ProcessingTimeInMilliseconds":"1"}
I'm guessing it's my formatting of my post request:
HTTP.post('http://api.ocr.space/parse/image',
{ "apikey":"helloworld", "language":"eng", "isOverlayRequired":"false", "file": "asssets/img/test2.pdf" }, {})
.then(data => {
console.log("HTTP entered");
let result = JSON.parse(data.data); // data received by server
console.log(data.data);
})
.catch(error => {
console.log(error.error); // error message as string
});
And I'm guessing this because I'm able to send PDF files successfully via postman like below: my successful postman request
So - I'd love some help figuring out how to send this HTTP.post request successfully or convert the code I can get from postman to successful ionic-native syntax.
var form = new FormData();
form.append("apikey", "541496f13e88957");
form.append("language", "eng");
form.append("isOverlayRequired", "false");
form.append("file", "1page.pdf");
var settings = {
"async": true,
"crossDomain": true,
"url": "https://api.ocr.space/parse/image",
"method": "POST",
"headers": {
"cache-control": "no-cache",
"postman-token": "1aea47d5-a0eb-7768-5fa6-60c4cd76d453"
},
"processData": false,
"contentType": false,
"mimeType": "multipart/form-data",
"data": form
}
$.ajax(settings).done(function (response) {
console.log(response);
});
I appreciate any and all help!
I'm using cordova-plugin-file-transfer to send file instead of Base64Image or for Ionic 2 using ionic-native with the examples

Worklight WL.Server.invokeHttp() with DELETE method doesn't accept query param

I have a Worklight adapter that calls a RESTful method through WL.Server.invokeHttp(). When an http DELETE method is used, the query string parameters do not get added. I'm on Worklight 6.0.
The input is setup like so:
{
"headers": {
"Accept": "application\/json",
"Authorization": "Bearer xxxxxxxxxxxxxxxx",
"Content-Type": "application\/json"
},
"method": "delete",
"parameters": {
"messageIds": "r11118,r11119"
},
"path": "\/myMessages\/v2\/messages"
}
and called like: var result=WL.Server.invokeHttp(input);
But I can see from Wireshark that the query params don't get added:
DELETE /myMessages/v2/messages HTTP/1.1\r\n
If all I do is change the method to a GET, the params are there on Wireshark:
GET /myMessages/v2/messages?messageIds=r11118%2Cr11119 HTTP/1.1\r\n
Sounds like a bug. We'll investigate it and fix in next releases if confirmed.

Resources