myshenin / aws-lambda-multipart-parser

Parser of multipart/form-data requests for AWS Lambda
MIT License
74 stars 38 forks source link

Issue parsing data on multipart/form-data message containing a series of parts #14

Open clicktravel-chrishern opened 6 years ago

clicktravel-chrishern commented 6 years ago

The library seems to work very well when I use it to parse data from a form with only one part but I am experiencing issues when parsing data from a form with multiple parts.

E.g. if my form is submitted with the following payload (all payloads taken from hitting the endpoint via Postman):

------WebKitFormBoundaryHi34dGTTK0UbQ0td
Content-Disposition: form-data; name="file"; filename="myfile.csv"
Content-Type: text/csv
------WebKitFormBoundaryHi34dGTTK0UbQ0td--

then I get correctly get when parsing the event in my Lambda:

{
    "file": {
        "type": "file",
        "filename": "myfile.csv",
        "contentType": "text/csv",
        "content": "filecontents"
    }
}

If I submit with a file part and a boolean part like this:

------WebKitFormBoundaryHi34dGTTK0UbQ0td
Content-Disposition: form-data; name="file"; filename="myfile.csv"
Content-Type: text/csv

------WebKitFormBoundaryHi34dGTTK0UbQ0td
Content-Disposition: form-data; name="preview"

true
------WebKitFormBoundaryHi34dGTTK0UbQ0td--

then the result of parsing is:

{
    "file": {
        "type": "file",
        "filename": "myfile.csv",
        "contentType": "text/csv",
        "content": "filecontents"
    }
}

The "preview" value is missing.

If I submit with only a "preview" value:

------WebKitFormBoundaryBnXclFeabewM9qcN
Content-Disposition: form-data; name="preview"

true
------WebKitFormBoundaryBnXclFeabewM9qcN--

then I correctly get this back after parsing:

{
    "preview": "true"
}

If I submit the "preview" parameter as the first part of the form and the file as the second then things get a bit weirder:

------WebKitFormBoundaryAgA0CHTJt4WM8G60
Content-Disposition: form-data; name="preview"

true
------WebKitFormBoundaryAgA0CHTJt4WM8G60
Content-Disposition: form-data; name="file"; filename="myfile.csv"
Content-Type: text/csv

------WebKitFormBoundaryAgA0CHTJt4WM8G60--

Result from parsing:

{
    "preview": {
        "type": "file",
        "filename": "myfile.csv",
        "contentType": "text/csv",
        "content": "true\r\n------WebKitFormBoundaryAgA0CHTJt4WM8G60\r\nContent-Disposition: form-data; name=\"file\"; filename=\"myfile.csv\"\r\nContent-Type: text/csv"
    }
}

I can make the parsing work for all of the above cases if I change lines 10 and 11 from:

.split(boundary)
.filter(item => item.match(/Content-Disposition/))

to

.split('Content-Disposition')
.filter(item => item.match(/form-data/))

But this is quite a significant change. Is there something am I missing in terms of some setup somewhere (in API Gateway for example) in order to get the current version working with multiple parts or is it a genuine issue?

Cheers, Chris

sergolius commented 6 years ago

@clicktravel-chrishern check https://github.com/sergolius/aws-lambda-multipart-parser Merge request on review