How to include file bytes into the POST request body in Jmeter? (What encoding to use) - rest

I have to perform POST requests from Jmeter. I use default HTTPRequest sampler, where I specify the JSON structure that is understandable by the testing app. One part of this JSON has to contain binary data from a pdf file.
For reading the file I use BeanShellSampler in the setUp thread group:
File file = new File(bsh.args[0]);
try {
FileInputStream fis = new FileInputStream(file);
byte[] array = new byte[(int)file.length()];
log.info("String is read.");
fis.read(array);
vars.put("fileEntity", new String(array, "cp1252"));
} catch (e) {
e.printStackTrace();
log.error(e.getMessage());
}
The problem is that when I look at the request with Fiddler, I see that difference, how the binary object is represented there in comparison with Postman's requests:
Postman
Jmeter
I think that there is something wrong with the encoding when I create a String object in the BeanShellSampler. What encoding is correct?
I tried to use RawDataSource plugin but it doesn't help for two reasons:
It fails to read my file, saying "Error reading next chunk"
It uses the same approach that I do to read the file, but uses UTF8 encoding. I tried this encoding also, but without any success.

My expectation is that your fis.read(array); function relies on default value of the file.encoding system property which may or may not be cp1252.
I would recommend introducing an InputStreamReader and explicitly specify the encoding there like:
InputStreamReader isr = new InputStreamReader(fis,"cp1252");
Also be aware that starting from JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting mainly because Groovy performs much better comparing to Beanshell.

Related

Explicitly setting `Content-Length` header in `java.net.http.HttpRequest`

I want to upload a file from InputStream over HTTP, and for this, I am using the new HttpClient provided as part of JDK11. When I try to set the Content-Length while creating a post request I get an IllegalArgumentException saying restricted header name: "Content-Length" and if I try to upload a file from InputStream without the Content-Length header I get an internal server error from the server where I want to upload the file. Is there any option to set the Content-Length in the request in Java 11?
CodeI am using for creating HttpRequest:
var postRequest = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofInputStream(() -> inputStream))
.uri(new URI(url))
.header(HttpHeaders.CONTENT_LENGTH, Long.toString(inputStreamSupplier.getFileSize()))
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
.build();
Note: It won't be possible to update to Java 12 to allow the restricted headers.
I could also use another library, just wanted to know if there is an option to use the classes from JDK before switching to RestTemplate from Spring. (yes, it's deprecated, As the alternative uses spring boot can't use it at the moment)
Simply use fromPublisher:
var bodyPublisher = BodyPublishers
.fromPublisher(BodyPublishers.ofInputStream(()-> inputStream)), length);
Note that you must ensure that the InputStream delivers exactly length bytes.

vertx-web httpserver messy code when response a Chinese word

I met an issue when I was learning Vert.x-Web, below code will return a messy code for Chinese words, any one can help?
HttpServer server = vertx.createHttpServer();
server.requestHandler(request -> {
// This handler gets called for each request that arrives on the server
HttpServerResponse response = request.response();
response.putHeader("content-type", "text/plain charset='utf-8'");
// Write to the response and end it
response.end("Hello World!中文");
});
server.listen(8080);
I just found the reason, I think actually vert.x support UTF-8 encoding, but we need to make sure all the html files and related files including css, js, and font files all match UTF-8 format while saving it. we can use notepad open the file and check if it is UTF-8 format, if not, use "Save As..." to save it as UTF-8 format.

NetSuite RESTlet output pdf

NetSuite Restlet PDF file encoding issue
The above thread seems to be giving a solution to outputing a pdf with a NetSuite RESTlet. As far as I know, you cannot output a pdf from a restlet, so I'm very confused. I am using a restlet to generate a report and the information ultimately needs to output to a pdf so I was trying to see if there was a work around. I tried the answer code from the above thread and I got the expected error:"error code: INVALID_RETURN_DATA_FORMAT error message:Invalid data format. You should return TEXT."
Am I missing something? Is there a way to export xml to a pdf with a NetSuite RESTlet?
The thread you reference discusses how to generate a PDF file in Netsuite. If you want to return a PDF from a RESTLet you will have to return it as a member of a JSON object. e.g.:
var pdfFile = genPDF(); // base this on the sample
return{
fileName: pdfFile.getName(),
fileContent: nlapiEncrypt(pdfFile.getValue(), 'base64')
};
And then your receiver will have to create the actual file.
Recall that RESTLets are for application-to-system communications. If you are trying to return a PDF to a browser you should probably be using a Suitelet.
If this is part of a larger app and you need the RESTLet then review this post: Save base64 string as PDF at client side with JavaScript for options to display the RESTLet response.
Reading through that answer, it appears you'll need to encode/convert the PDF to string format before returning, so you'll need to use base64 encoding.
The NS method nlapiEncrypt(content, 'base64') seems like it might be a good place to start.
Another avenue to investigate, which I haven't tried, is to first save the PDF in the file cabinet, then to return a public link to that file. You'll need to make sure the file has the correct permissions.

HTTP reading and rewriting bytes

I am getting a blob of binary data by executing a command-line program. This blob can be decoded by the same program.
I would like to send this binary data in a HTTP response. For that I use the "application/octet-stream" mime-type (I also tried "text/plain"). But when the client gets the data on the other end, it is not readable anymore. The format has changed somehow.
Here is my Scala code (but I think it is a generic question):
val command = s"samtools view -h $testbam $region"
val res: String = command.!! // Gets the stdout as string
Result(
header = ResponseHeader(200, Map.empty),
body = HttpEntity.Strict(ByteString(res), Some("application/octet-stream"))
)
The same command, run on the command-line, can be decoded properly. But the result of a "curl" here, although it does return a bunch of unreadable symbols, cannot be decoded.
Sending the same data in its readable (uncompressed) form goes through properly without losing content or formatting.
What kind of characters conversion am I missing ? Any encoding to specify ?
Edit: Play 2.5.0

httprequest encoding mismatch

I'm using a Google Gears Worker to submt a POST httprequest (using var request = google.gears.factory.create('beta.httprequest'); )
with a parameter containing the string
"bford%20%24%23%26!%3F%40%20%E5%BE%B3%E5%8A%9B%E5%9F%BA%E5%BD%A6"
but the Django HttpRequest is receiving it as "bford $#&!?# å¾³å\u008a\u009bå\u009fºå½¦"
How do I specify to one or the other of the parties in the transaction to leave it untranslated?
Check the HttpRequest.encoding and the DEFAULT_CHARSET settings. Judging by the encoded value, this should be UTF-8 (which is indeed usually the right thing).
You can get the ‘untranslated’ (with %s still in) value by looking at the input stream (for POST) or environ QUERY_STRING (for GET) and decoding it manually, but it would be better to fix Django's incorrect string-to-unicode decoding really.
As I understand it, Django 1.0 should default to using UTF-8, so I'm not sure why it's not in your case.