Rest Assured - Send POST Request (Content-Type : multipart/form-data) with Static JSON Payload and Files to be uploaded - rest-assured

I want to send a POST Request where -
Content Type is "multipart / form-data".
In "Body" section, I have 2 params -> body - {static JSON Payload}, files - {any file, say .log file}
In Rest Assured Code, I am able to get the Static JSON Payload in String format with below code -
String jsonFilePath = "<<Path to JSON File>>/Test_new.json";
String response = given().log().all().header("X-AUTH-TOKEN",res).body(new String(Files.readAllBytes(Paths.get(jsonFilePath)))).
when().post("<<POST RESOURCE URL>>").
then().log().body().assertThat().statusCode(200).extract().response().asString();
When running this code, only with Static JSON Payload, I am getting "415" error code.
Questions -
How can we successfully make this kind of call in Rest Assured?
When I want to upload files as well with this call, how to do that?

You need to use multiPart() methods for uploading files, not body() method. For example:
File json = new File("src/test/resources/test_new.json");
File file = new File("src/test/resources/debug.log");
given().log().all()
.multiPart("files", file)
.multiPart("body", json, "application/json")
.post("your_url");

Related

How do you send MIME format emails using Microsoft Graph Java SDK?

The official documentation does not provide an example for any SDK's (including the Java SDK): https://learn.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=java#example-4-send-a-new-message-using-mime-format. As there is no example, I have tried in vain to send the MIME content using the SDK (microsoft-graph 5.0.0):
Message sending = new Message();
ItemBody body = new ItemBody();
final String mimeMessageRFC822 = input.getMimeMessageRFC822();
body.content = Base64.getMimeEncoder().encodeToString(mimeMessageRFC822.getBytes());
sending.body = body;
GraphServiceClient service = getService(acHost, configuration);
service
.me()
.sendMail(UserSendMailParameterSet.newBuilder().withMessage(sending).withSaveToSentItems(true).build())
.buildRequest(new HeaderOption("Content-Type", "text/plain"))
.post();
The above code sets the request's content-type to text/plain, however the request body that is being sent is JSON (xxxxxx below is a placeholder for a valid Base64 encoded MIME content string).
{
"message":
{
"body":
{
"content": xxxxxx
}
},
"saveToSentItems": true
}
The response is a 404, stating:
GraphServiceException: Error code: ErrorMimeContentInvalidBase64String
Error message: Invalid base64 string for MIME content.
I can understand why it is responding with this error as the graph endpoint is parsing the text/plain content as base64 encoded MIME but finds the JSON structure instead. I have been on a video call with a Microsoft Graph support agent, and they have seen that my MIME content is valid. Sadly, they are not able to help with the Microsoft Graph Java SDK even though it is developed by Microsoft!
This suggests that we are not supposed to use the Java SDK at all for sending MIME formatted emails. Is this correct? Surely it can't be otherwise what is the point of a library that can receive MIME formatted emails but can't send them? Does anyone have a solution?
For now at least the solution is to send a CustomRequest with MIME content instead of using the fluent API provided by the Graph client.
final String encodedContent = Base64.getMimeEncoder().encodeToString(mimeMessageRFC822.getBytes());
CustomRequest<String> request = new CustomRequest<>(requestUrl, service, List.of(new HeaderOption("Content-Type", "text/plain")), String.class);
request.post(encodedContent);

Microsoft Graph (OneDrive) API - Resumable Upload Content-Type

I am trying to create the upload PUT request for the OneDrive API. It's the large file "resumable upload" version which requires the createUploadSession.
I have read the Microsoft docs here: As a warning the docs are VERY inaccurate and full of factual errors...
The docs simply say:
PUT
https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337Content-Length:
26Content-Range: bytes 0-25/128 <bytes 0-25 of the
file>
I am authenticated and have the upload session created, however when I pass the JSON body containing my binary file I receive this error:
{ "error": {
"code": "BadRequest",
"message": "Property file in payload has a value that does not match schema.", .....
Can anyone point me at the schema definition? Or explain how the JSON should be constructed?
As a side question, am I right in using "application/json" for this at all? What format should the request use?
Just to confirm, I am able to see the temp file created ready and waiting on OneDrive for the upload, so I know I'm close.
Thanks for any help!
If you're uploading the entire file in a single request then why do you use upload session when you can use the simple PUT request?
url = https://graph.microsoft.com/v1.0/{user_id}/items/{parent_folder_ref_id}:/{filename}:/content
and "Content-Type": "text/plain" header and in body simply put the file bytes.
If for some reason I don't understand you have to use single-chunk upload session then:
Create upload session (you didn't specified any problems here so i'm not elaborating)
Get uploadUrl from createUploadSession response and send PUT request with the following headers:
2.1 "Content-Length": str(file_size_in_bytes)
2.2 "Content-Range": "bytes 0-{file_size_in_bytes - 1}/{file_size_in_bytes}"
2.3 "Content-Type": "text/plain"
Pass the file bytes in body.
Note that in the PUT request the body is not json but simply bytes (as specified by the content-type header.
Also note that max chuck size is 4MB so if your file is larger than that, you will have to split into more than one chunks.
Goodlcuk

Proxying MultiPart form requests in Grails

I have a Grails controller that receives a DefaultMultipartHttpServletRequest like so:
def myController() {
DefaultMultipartHttpServletRequest proxyRequest = (DefaultMultipartHttpServletRequest) request
}
This controller acts as a proxy by taking pieces of this request and then resends the request to another destination.
For non-multipart requests, this worked fine, I did something like:
IProxyService service = (IProxyService) clientFactory.create()
Response response = service.doPOST(proxyRequest.getRequestBody())
Where proxyRequest.getRequestBody() contains a JSON block containing the request payload.
However, I do not know how to get this to work with multipart request payload, since the request body is no longer a simple block of JSON, but something like the following (taken from Chrome devtools):
How can I can pass this request payload through using my proxy service above, where doPost takes a String?
Have you tried
def parameterValue = request.getParameter("parameterName")
to get the parameter value?
If you see the method signatures for DefaultMultipartHttpServletRequest you will see there are methods for getting the files and other parameters separately because the request body is getting used to both upload the file and to pass in other parameters.

How to capture http POST requests with browsermob-proxy and selenium

Hello trying to capture the actual POST data in an HTTP POST request using browsermob proxy + selenium test framework. So basically i'm running an automated test using selenium and I want to capture the key/value pairs and the actual POST data of a HTTP POST request during the test. Using the following logic I can only capture the key/value pairs of the POST header but not the actual POST data (aka the form field id values). Is there a way to actually capture the POSTDATA (like sniffing applications do such as tamper/live headers in firefox)?
ProxyServer proxyServer = null;
proxyServer = new ProxyServer(9101);
proxyServer.start();
proxyServer.setCaptureContent(true);
proxyServer.setCaptureHeaders(true);
Proxy proxy = proxyServer.seleniumProxy();
proxy.setHttpProxy("localhost:9101");
//selenium test config code, omitted for brevity
proxyServer.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
Header[] headers = request.getAllHeaders();
System.out.println("\nRequest Headers\n\n");
for(Header h : headers) {
System.out.println("Key: " + h.getName() + " | Value: " + h.getValue());
}
}
});
An alternate way I read about but could not get to work was to configure the following flags in the browsermob proxy server to true:
proxyServer.setCaptureContent(true);
proxyServer.setCaptureHeaders(true);
Then output the actual HAR file:
Har har = proxyServer.getHar();
Date date = new Date();
har.writeTo(new File("c:\\tmp\\har_" + date.getTime()));
To see the key/value pairs, POST Data, and actual content of the response... but when I parse the HAR file... I only see the key/value pairs of the POST header again... no POST data... no response content. I am only interested in the actual POST data though.
I also had same problem. As a solution, I captured all the data, converted the HAR file into JSON, and then filtered out only POST requests from the JSON file.

HTTPBuilder HTTP Post url encoded parameters and accept xml response?

Hi there i am wondering how i can post a urlencoded string and read in an xml response using HTTPBuilder? I would like to use this inside a Grails application. The REST plugin is no option. I tried the examples given on http://groovy.codehaus.org/modules/http-builder/doc/post.html but this gives me no xml response to read in.
You can try something like this:
def httpBuilder = new HTTPBuilder("http://webite.url")
httpBuilder.request(Method.POST, URLENC){req->
headers.accept = "application/xml"
body = [ YOUR URL ENCODED POST]
response.success = {resp,xml->
//read xml response.
}
}

Resources