Skip to content

fix: use the requests content-type for request signing#92

Merged
tlovrec-form3 merged 2 commits into
masterfrom
tl-req-sign-content-type
May 28, 2026
Merged

fix: use the requests content-type for request signing#92
tlovrec-form3 merged 2 commits into
masterfrom
tl-req-sign-content-type

Conversation

@tlovrec-form3
Copy link
Copy Markdown
Contributor

@tlovrec-form3 tlovrec-form3 commented May 15, 2026

Summary

Request signing always used application/vnd.api+json and req.ContentLength, which broke multipart and other non-JSON bodies. Sign and set headers from the actual body bytes and the request's Content-Type (defaulting when unset). Replace deprecated ioutil with io.

Proof of work

 ~/dev/projects/form3-oss/go-form3 > tl-req-sign-content-type $ make test
go test -v -race -cover ./pkg/form3
=== RUN   TestRequestSigningAuth
--- PASS: TestRequestSigningAuth (0.28s)
=== RUN   TestWithUserAgent
=== RUN   TestWithUserAgent/Default
=== RUN   TestWithUserAgent/Custom_User_Agent
--- PASS: TestWithUserAgent (0.41s)
    --- PASS: TestWithUserAgent/Default (0.00s)
    --- PASS: TestWithUserAgent/Custom_User_Agent (0.00s)
=== RUN   TestRequestSigningTransportPOSTJSONBodySigning
--- PASS: TestRequestSigningTransportPOSTJSONBodySigning (0.19s)
=== RUN   TestRequestSigningTransportPOSTMultipartBodySigning
--- PASS: TestRequestSigningTransportPOSTMultipartBodySigning (0.35s)
=== RUN   TestTokenAuth
--- PASS: TestTokenAuth (0.59s)
=== RUN   TestMTLS
--- PASS: TestMTLS (0.02s)
=== RUN   TestQueryPayments
--- PASS: TestQueryPayments (0.74s)
=== RUN   TestPaymentFromJsonFile
--- PASS: TestPaymentFromJsonFile (0.00s)
=== RUN   TestPaymentToJson
--- PASS: TestPaymentToJson (0.00s)
=== RUN   Test_ResponseInterface
--- PASS: Test_ResponseInterface (0.00s)
=== RUN   TestCreateSubscriptionsDeprecatedCallbackUriParams
--- PASS: TestCreateSubscriptionsDeprecatedCallbackUriParams (0.28s)
=== RUN   TestCreateSubscriptionsNewCallbackUriParams
--- PASS: TestCreateSubscriptionsNewCallbackUriParams (0.26s)
=== RUN   TestCreateSubscriptionsNewCallbackUriParamsHttpAwsPrivate
--- PASS: TestCreateSubscriptionsNewCallbackUriParamsHttpAwsPrivate (0.26s)
=== RUN   TestListSubscriptions
--- PASS: TestListSubscriptions (0.08s)
PASS
coverage: 77.1% of statements
ok      github.com/form3tech-oss/go-form3/v7/pkg/form3  5.037s  coverage: 77.1% of statements

@tlovrec-form3 tlovrec-form3 requested a review from a team as a code owner May 15, 2026 09:00
mlornac
mlornac previously approved these changes May 26, 2026
req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
req.Header.Set("Content-Type", ReqMimeType)
req.Body = io.NopCloser(bytes.NewBuffer(body))
req.ContentLength = contentLength
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if it's actually required to compute the content length manually? It seems like something that should be handled by net/http internally?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

net/http should normally have this right already. I kept the assignment because the signer reads and rebuilds the body before generating the signature, so using the buffered body length felt like the safest way to keep the signed content-length in sync with the exact bytes being replayed. Happy to drop it if that feels too defensive.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense!

@tlovrec-form3 tlovrec-form3 merged commit 5adfcbc into master May 28, 2026
1 check passed
@tlovrec-form3 tlovrec-form3 deleted the tl-req-sign-content-type branch May 28, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants