I have a request made to server like
curl -H 'Host: test.apigee.net' -H 'Content-Type: multipart/form-data; boundary=beachbodyboundarystring' -H 'Accept: application/json' -H 'Accept-Language: en-us'
-H 'User-Agent: BOD/9 CFNetwork/808.0.2 Darwin/16.0.0' --data-binary '--beachbodyboundarystring
Content-Disposition: form-data; name="sourceSystem" appletv --beachbodyboundarystring Content-Disposition: form-data; name="email" test@test.com ' --compressed 'https://test.apigee.net/user/callAPI'
I need to use Apigee to convert this POST into GET call and passing the email from FORM data as query string.
I am unable to extract the FORM data, I don't want to use Javascript as that is slowing the call by >1000 ms.
Here is what my policy looks like.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AssignMessage async="false" continueOnError="false" enabled="true" name="ChangeRequestMethod"> <DisplayName>ChangeRequestMethod</DisplayName> <Properties/> <Copy source="request"> <Headers/> <QueryParams/> <FormParams> <FormParam name="sourceSystem"/> </FormParams> <Payload/> <Verb/> <StatusCode/> <ReasonPhrase/> <Path/> </Copy> <Remove> <FormParams> <FormParam name="email"/> <FormParam name="guid"/> </FormParams> <Payload/> </Remove> <Add> <QueryParams> <QueryParam name="email">{request.content}</QueryParam> <QueryParam name="guid">{request.formparam.sourceSystem}</QueryParam> </QueryParams> </Add> </AssignMessage>
Solved! Go to Solution.
A couple things for you
Let me know if I can help further. I will be glad to look at your code, if you care to share it.
Here's some additional help, in case you decide to stick with the multipart/form-data payload.
This JS can be used to naively process a multi-part form of the kind you showed. (It will not work for the general case!)
// processMultipartForm.js // ------------------------------------------------------------------ // // process a simple multipart form. This works only with single-line data items. // var ctype = context.getVariable('request.header.content-type'); var re1 = new RegExp('^multipart/form-data; *boundary=(.+)$'); var match = re1.exec(ctype); var boundary = match[1]; var blength = boundary.length; var body = context.getVariable('request.content'); var re2 = new RegExp('^--' + boundary + '$', 'gm'); var re3 = new RegExp('^Content-Disposition: form-data; name="(.+)"$[\r\n]+(.+)$', 'm'); var section; var payload = {}; while ((section = re2.exec(body)) !== null) { var start = section.index + blength + 1; var blob = body.substring(start, section.lastIndex); match = re3.exec(blob); if (match) { context.setVariable('extracted_' + match[1], match[2]); payload[match[1]] = match[2]; } } context.setVariable('resp_payload', JSON.stringify(payload, null, 2));
I just tried this and get these results. It takes about 5 ms for this entire proxy to run.
Request:
$ curl -i -X POST \ -H 'Content-Type: multipart/form-data; boundary=beachbodyboundarystring' \ -H 'Accept: application/json' \ -H 'Accept-Language: en-us' \ -H 'User-Agent: BOD/9 CFNetwork/808.0.2 Darwin/16.0.0' \ --data-binary ' --beachbodyboundarystring Content-Disposition: form-data; name="sourceSystem" appletv --beachbodyboundarystring Content-Disposition: form-data; name="email" test@test.com --beachbodyboundarystring--' \ --compressed 'https://MYORG-test.apigee.net/multipart-form-1/t1'
Response:
HTTP/1.1 200 OK Date: Sat, 14 Jan 2017 01:49:32 GMT Content-Type: application/json Content-Length: 61 Connection: keep-alive Accept-Encoding: deflate, gzip Accept-Language: en-us Server: Apigee Router { "sourceSystem": "appletv", "email": "test@test.com" }
See the attached proxy bundle for working code.