Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Copy a file from proxy request to target rest service

Not applicable

Hi All,

I have a proxy that accepts an uploaded file as part of multipart/form-data request. I would like to pass the uploaded file on to a target rest server.

What is the best way to approach this? Currently, I'm using an assign-message policy that copies the incoming request and modifies it into the request that target expects i.e.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="PassthroughAssign">
    <DisplayName>PassthroughAssign</DisplayName>
    <Properties/>
    <Copy source="request">
        <Headers/>
        <FormParams/>
        <Payload/>
        <Verb/>
    </Copy>
    <Remove>
        <Headers>
            <Header name="jwt"/>
        </Headers>
    </Remove>
    <Add>
        <Headers>
            <Header name="x-facade-token">XXXX-XXXXXXXXXXX-XXXXXXXXXXXX</Header>
        </Headers>
    </Add>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="true" transport="http" type="request">target.passthru</AssignTo>
</AssignMessage>

...and then I use a callout policy to call the target rest service i.e.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="Call-File-Upload-Service">
    <DisplayName>Call File Upload Service</DisplayName>
    <Properties/>
    <Request clearPayload="false" variable="target.passthru">
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    </Request>
    <Response>openTextResponse</Response>
    <HTTPTargetConnection>
        <Properties>
            <Property name="success.codes">1xx,2xx,3xx,4xx,5xx</Property>
        </Properties>
        <URL>http://{ot.host}/{ot.base.path}/workspace/{target.clientId}/{target.workspacePath}</URL>
    </HTTPTargetConnection>
</ServiceCallout>

However, the target server responds with an error 500 - "unexpected end of input".

Is there something I'm doing obviously wrong? Should I handle this differently?

Solved Solved
1 4 1,722
1 ACCEPTED SOLUTION

Not applicable

After much wrangling, I managed to solve the issue - actually a couple of issues

The quick one to resolve (after getting a view of the request sent out) was the fact that my content body was missing. This is because my initial <copy> from my question needed to look more like this:

<Copy source="request">
        <Headers/>
        <Payload>true</Payload>
        <Verb>true</Verb>
    </Copy>

I eventually shifted away from the copy and built a new request (due to a change of requirements)

The more difficult issue to resolve (and having a more annoying resolution) was that content length was being calculated incorrectly. The answer lay in my AssignMessage policy which looked as follows:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage name="PassthroughAssign">
    <DisplayName>PassthroughAssign</DisplayName>
    <Set>
        <Headers>
            <Header name="x-facade-token">XXXXXXXXXXXXXXXXXXX</Header>
            <Header name="Content-Type">multipart/form-data; boundary={boundary}</Header>
            <Header name="content-length">{multipartLength}</Header>
        </Headers>
        <Verb>POST</Verb>
        <Payload variablePrefix="@" variableSuffix="#">
            @multipart#
        </Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="true" transport="http" type="request">target.passthru</AssignTo>
</AssignMessage>

I found out that the formatting inside the <Payload> tag was actually being added to the payload. i.e. apigee was sending "\n {contents of multipart}". So payload ended up larger than my contentLength header. Also, because there were spaces before the payload boundary, the target server would reject the message.

I changed the <Payload> XML to look as follows:

<Payload variablePrefix="@" variableSuffix="#">@multipart#</Payload>

That resolved my issues. Thanks for your assistance @Dino

View solution in original post

4 REPLIES 4