Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent dynamic boundaries on multipart/form-data pacts #1792

Closed
marcozet opened this issue Apr 29, 2024 · 2 comments
Closed

Prevent dynamic boundaries on multipart/form-data pacts #1792

marcozet opened this issue Apr 29, 2024 · 2 comments
Labels
question Indicates that an issue, pull request, or discussion needs more information

Comments

@marcozet
Copy link

marcozet commented Apr 29, 2024

We have a scenario where we need to upload a bunch of files using post with Content-Type multipart/form-data.

So the request body looks like...

--m5owueqDDBp_nPEBOX-JvuMixxacXChqVMnc6
Content-Disposition: form-data; name="files"; filename="foo.txt"
Content-Type: text/plain

foo
--m5owueqDDBp_nPEBOX-JvuMixxacXChqVMnc6
Content-Disposition: form-data; name="files"; filename="bar.txt"
Content-Type: text/plain

bar
--m5owueqDDBp_nPEBOX-JvuMixxacXChqVMnc6--

and the Pact is generated as...

@Pact(consumer = "consumer-service", provider = "file-upload-service")
public RequestResponsePact upload(PactDslWithProvider builder) throws IOException {
    DslPart responseBody = newJsonBody((body) -> {
                body.uuid("uploadId")
    })
    .build();

    return builder.given("001: no data available")
            .uponReceiving("request to upload a file")
            .path(BASE_URI + "/uploads")
            .method("POST")
            .headers(Map.of("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE))
            .withFileUpload(
                    "files",
                    "bar.txt",
                    "application/octet-stream",
                    new ClassPathResource("foo.txt").getContentAsByteArray())
            .withFileUpload(
                    "file",
                    "foo.txt",
                    "application/octet-stream",
                    new ClassPathResource("bar.txt").getContentAsByteArray())
            .willRespondWith()
            .status(HttpStatus.OK.value())
            .body(responseBody)
            .toPact();
}

No issues so far.

We use the Pact Broker / Pact webhook workflow, so we publish the Pact file to the broker and the provider verification is triggered via the webhook when the content of the Pact file has changed (on contract_content_changed event).

But unfortunately, the generated and published Pact file differs from test run to test run, as the boundary in the request body that marks the various parts is generated dynamically.

As a result, the Pact broker triggers the provider verification for each consumer build, even though the Pact itself has not been changed (except for the boundary attribute).

Can I set the boundary attribute statically so that the Pact doesn't change?

I found a similar problem here: pact-foundation/pact-net#410 (comment)

@marcozet marcozet changed the title Can I prevent dynamic boundaries on multipart/form-data requests? Prevent dynamic boundaries on multipart/form-data pacts Apr 30, 2024
@rholshausen rholshausen added the question Indicates that an issue, pull request, or discussion needs more information label May 3, 2024
@rholshausen
Copy link
Contributor

If you use the MultipartEntityBuilder from the Apache HTTP client, you can set the boundary to a fixed value (using setBoundary).

Example test using MultipartEntityBuilder

@marcozet
Copy link
Author

marcozet commented May 6, 2024

OK, got it! Now it works... Thanks.

@marcozet marcozet closed this as completed May 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Indicates that an issue, pull request, or discussion needs more information
Projects
None yet
Development

No branches or pull requests

2 participants