Parse multipart/form-data json body of lambda in Java - amazon-web-services

I am trying to implement a Lambda function that receives a POST request containing data encoded as multipart/form-data. The message is received through the API Gateway using Lambda Proxy integration and the body is encoded in Base64 when it arrives to the Lambda function. After decoding it manually, I see it contains a multipart body like the following:
-----WebKitFormBoundary3EZ0C3tbP2JpAmz4
Content-Disposition: form-data; name="param1"
value1
-----WebKitFormBoundary3EZ0C3tbP2JpAmz4
Content-Disposition: form-data; name="param2"
value2
------WebKitFormBoundary3EZ0C3tbP2JpAmz4
Content-Disposition: form-data; name="myfile"; filename="ivr.png"
Content-Type: image/png
PNG
... [binary stuff]
------WebKitFormBoundary3EZ0C3tbP2JpAmz4--
What I need is to parse this message in java 8.
so that I can access the individual parts like
1. form data
2 file content
I have tried fileupload, Apache Multipart those didn't workout
Any sols will be helpful.

I ran into a similar issue with my application. I used and modified a custom form-data parser here: https://apimeister.com/2015/10/10/formdatahandler-implements-com-sun-net-httpserver-httphandler.html
I got it to parse properly however, the binary data came in malformed similar to this issue here: https://github.com/dherault/serverless-offline/issues/230
How did you get the entire AWS Lambda body to encode to base64? Can you post instructions to do so? That may fix the malformed data issue I am running into.

Related

Upload file test with Postman

I am testing a file upload to SharePoint online with Postman. In my post request I set the body to form-data and add a file param with a text file called a.txt. The text file contains the text
one
two
three
When I execute the request my file is uploaded but when I open the file the contents is
----------------------------235004993628819232914336
Content-Disposition: form-data; name="file"; filename="a.txt"
Content-Type: text/plain
one
two
three
----------------------------235004
I have tried setting the Content-Type header to
application/x-www-form-urlencoded
or
multipart/form-data
But no luck
Please follow the below steps-
1. Go to the body of the API
2. pass the parameter or key
3. When you pass the key you have a option of value of Text/File like below
4.Choose the file from
5. Click on send.
6. Get your response.
Hope this helps buddy.
In my case setting the body to type binary solved my problem with testing with Postman

how to set text/plain content-type in api gateway

I have an api gateway that is pointed to s3 and it reads the document and sends back the contents, about 5 paragraphs. It works great, however the content-type on the response is binary\octet-stream. For app integration it would be better if this was text\plain as it is just plain text. I have tried to set this as a parameter on the request with response-content-type. I have also tried to map it within the api gateway integration response. If I leave off the Content-Type mapping I get application/json instead. I've followed the docs here: https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html
The Content-Type on the s3 object was set to binary/octet-stream. Set this to text/plain and works great now!

AWS LAMBDA: Accessing request headers and body of different content types?

I'm trying to deploy a lambda function with aws api gateway. I was able to succesfully deploy and test POST and GET methods with Content-Type: application/json by following this blog: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/
I want my same lambda function to handle requests of content-type : text/plain, x-www-form-urlencoded also.
The problem with integration template is that we have to define the content-type before hand. So if I make a integration template of Content-type: text/plain how can I call that integration template when the api request of text/plain is made to the url.
How can I invoke different integration templates based on the Content-Type of the api request?
any tips on that?
Thanks.
I don't know whether I got your problem right r not.
From my understanding if you are passing any header information or query string parameters and the content type is text/plain you can map the template like this
{
"prod_Id" : "$input.params('prod_Id')"
}
where product id can be the header or query string parameter.
you can find it in my blog in 'how to pass query string section

request.POST empty for Content-Type: multipart/form-data; boundary=xYzZY

[SOLVED] Please see my answer.
Any POST request sent with the
Content-Type: multipart/form-data; boundary=xYzZY results in the request.POST QueryDict{} to be empty. Changing the Content-Type to multipart/form-data also results in the same error.
Removing the Content-Type altogether results in the values getting passed correctly, and I can access them in request.POST.
I have tried disabling the Csrf middleware, using #csrf_exempt, and also tried the same on multiple servers. Didn't change the empty POST condition.
While reading up on Django framework and POST content-type, I read that it (no longer) assumes a default content-type and therefore must be supplied with the correct one (I do not have a link to the article in question.) I think something similar is happening here, with django not being able to parse the parameters with the given content-type (but leaving it blank lets the parser interpret it with the default value).
What I am having trouble with is, that the Content-Type value supplied is perfectly valid (multipart/form-data with boundary). So why does django refuse to load it in the POST dictionary?
** I am not in control of the Content-Type sent in the POST data.
** UPDATE: reading from request.body shows that all the POST parameters are being received. They're just not present in request.POST
** UPDATE: I'm using Runscope to test POST requests.
As mentioned in the UPDATE, I was using Runscope to test the POST data. I realised that the error was with the way Runscope handled multipart/form-data. I raised the issue with support and got notified that Runscope does not support multipart as of now. I've copied the relevant information here:
We hope to support multipart form uploads capabilities for the future, but don't have a timeline on when this will be available. Some customers have made this work in their Radar tests (https://www.runscope.com/docs/radar) by pasting in the raw multipart-formatted body or unicode string input body into the request and making sure to include the applicable 'Content-type' header value with the correct boundaries. Some examples for building a multipart/form-data POST request can be found here: http://chxo.com/be2/20050724_93bf.html
For Runscope URLs, multipart data is passed through unmodified. However, the request editor and retries from the Traffic Inspector (https://www.runscope.com/docs/inspector) do not currently support multipart data which is why your request retry did not work. Additionally, request and response bodies larger than 1 MB are not saved for viewing after the request has been sent.
Using another service solved this for me.
You are (in a manner) in control of Content-Type. What you're looking for is enctype. You can use it as following:
<form method="POST" action="." enctype="multipart/form-data">
enctype is only required when you are uploading a file, otherwise, it's not.

About multipart/form-data and boundary=MIMEBoundary_*

Currently i am using WSO2 API manager 1.8.0 to secure my web service endpoints . There is a end point allow to upload file and text (multipart/form-data). Firstly, I have invoked the endpoint directly and got success. Then i create a API by using WSO2 AM and provide upload file end point for production and sandbox url. After invoked, i got exception regarding to "Body part ended prematurely. Boundary detected in header or EOF reached."
I have investigated and see that the content type is changed
This is the correct one:
Content-Type: multipart/form-data; boundary=a65f7a9e-30a7-41ce-986b-e0ba8678cd7d
--a65f7a9e-30a7-41ce-986b-e0ba8678cd7d
Content-Disposition: form-data; name="type"
Content-Type: application/x-www-form-urlencoded
MY_DA_TA
--a65f7a9e-30a7-41ce-986b-e0ba8678cd7d--
And this is the difference
Content-Type: multipart/form-data; charset=UTF-8; boundary=MIMEBoundary_f7e66aa74d83cdf3eca30fd8f62eff42fd5b2e5d627e4e78
--2819d1cd-319b-4d7b-9685-b9944b6e22e5
Content-Disposition: form-data; name="type"
Content-Type: application/x-www-form-urlencoded
MY_DA_TA
--2819d1cd-319b-4d7b-9685-b9944b6e22e5--
How can i correct that ?
Just by glance I found a similar query [1]. Could you check if that works for you.
[1] multipart form data file upload using WSO2 API manger ?