This scenario <Request with a binary body (negativ...
# libpact_ffi-users
t
This scenario Request with a binary body (negative case) doesn't look right to me.
Copy code
Scenario: Request with a binary body (negative case)
    When the mock server is started with interaction 7
    And request 7 is made to the mock server with the following changes:
      | body             |
      | file: spider.jpg |
    Then a 500 error response is returned
    And the mismatches will contain a "body" mismatch with error "Actual body [image/jpeg, 30922 bytes, starting with ffd8ffe000104a46494600010101004800480000ffe100ae4578696600004949] is not equal to the expected body [image/jpeg, 28058 bytes, starting with ffd8ffe000104a46494600010101012c012c0000ffe12db64578696600004949]"
According to document of pactffi_with_binary_file:
Will use a mime type matcher to match the body.
I think the content of the binary file doesn't matter. If we change the content of the binary file, as long as the mime type doesn't change (image/jpeg), the mock server shouldn't consider this as a mismatch . The response code should be 200, not 500.
r
That's a V1 scenario, which is not using any matching rules. Matching rules are added as part of V2, and the content type matcher is V3.
t
facepalm2 I didn't think about it
🤔 I did select the specification v1, but the response code is 200, not 500 as expected. Not sure what cause it
m
pactffi_with_binary_file:
I think this is V3 only, right Ron? It’s what adds the matcher Ron’s talking about. In V1 (and V2), you wouldn’t use this function directly.
(please confirm that is correct Ron)
r
Yes
👍 1
t
I only see 2 options to set the body of the request: •
pactffi_with_body
•
pactffi_with_binary_file
If I can't use
pactffi_with_binary_file
, so
pactffi_with_body
is the only option. Does
pactffi_with_body
support binary?
I don't think
pactffi_with_body
support binary. So I updated
pactffi_with_binary_file
to add matching rule conditionally https://github.com/pact-foundation/pact-reference/pull/327
m
I think there is a way to pass binary data to the other method
The definition of
pactffi_with_body
accepts binary in the
body
attribute
Copy code
bool pactffi_with_body(InteractionHandle interaction,
                       enum InteractionPart part,
                       const char *content_type,
                       const char *body);
In Pact Go, this is used for all body types, including binary. i.e. you can pass byte arrays to this type
r
The main problem is that the type for the body is
const char *
which can't have any zero bytes in it and must be ended with a NULL terminator
☝️ 1
m
Ask me how I know that… (not sure why I made that a TODO)
j/k, the C interface method description explains this:
Copy code
...
 * # Safety
 *
 * The content type must be a valid UTF-8 encoded NULL-terminated string. The body pointer must
 * be valid for reads of `size` bytes, and it must be properly aligned and consecutive.
...
r
That's the description for
pactffi_with_binary_file
m
I might have an old/outdated copy of the
pact.h
vendored in the go repo (it’s not linked to code, but there as a reference. Perhaps it should be removed now)
t
This is the message I got when using
pactffi_with_body
with binary string:
Copy code
2023-10-14T02:55:28.212556Z TRACE ThreadId(01) pact_ffi::mock_server::handles: >>> pactffi_with_body(InteractionHandle { interaction_ref: 65537 }, Request, 0x7f0658eb9360, 0x7f0658f24018)
2023-10-14T02:55:28.212564Z  WARN ThreadId(01) pact_ffi: Failed to parse body name as a UTF-8 string: invalid utf-8 sequence of 1 bytes from index 0
This is why I think it doesn't support binary string. Sorry I forgot to mention it.
m
How are you calling it?
t
I'm not sure I understand the question.
y
i think Matt means what arguments are you passing to the function, when you get the failure above
☝️ 1
Copy code
$ffi->pactffi_with_body($interaction, $ffi->InteractionPart_Response, 'image/jpeg', file_get_contents(__DIR__ . '/../../compatibility-suite/pact-compatibility-suite/fixtures/spider.jpg'));
2023-10-17T121640.733118Z WARN ThreadId(01) pact_ffi: Failed to parse body name as a UTF-8 string: invalid utf-8 sequence of 1 bytes from index 0
y
ty for the simple reproducer, I will take a look later today after the workshop and see what behaviour
I think PHP FFI’s interface should add the NULL terminator - some lang’s dont such as deno https://github.com/YOU54F/deno-pact/blob/dbe83e74311263cf93621106803a3468e8e17a95/src/lib/safe-ffi.ts#L20-L24
as its fine with reading with the content type which is also the same type
const char *
m
Failed to parse body name
that’s a bit confusing, what’s “name” in this context. Might need to improve that error message
j
Sorry to revive an old thread, but I've also run across the same issue (which suggests we might need to update the Rust FFI docs, or the FFI itself). I naively tried to also use the
with_binary_file
to pass byte arrays which are invalid UTF-8 sequences. I think it might be worth tracking in a ticket on GitHub (which I'm starting to write now).