Skip to content

Add body_from config to step.http_call for raw body forwarding#227

Merged
intel352 merged 4 commits intomainfrom
copilot/add-body-from-config-http-call
Mar 2, 2026
Merged

Add body_from config to step.http_call for raw body forwarding#227
intel352 merged 4 commits intomainfrom
copilot/add-body-from-config-http-call

Conversation

Copy link
Contributor

Copilot AI commented Mar 2, 2026

  • Understand existing body_from / _from pattern in json_response and raw_response steps
  • Add bodyFrom field to HTTPCallStep struct
  • Parse body_from config key in the factory function
  • Update buildBodyReader() to check bodyFrom first (raw bytes, no JSON encoding)
  • Avoid auto-setting Content-Type: application/json when using body_from
  • Add tests for body_from with string, []byte, step output path, Content-Type override, and nil values
  • Run tests to validate changes (all pass)
  • Fix data race in tests: use buffered channels instead of shared variables between handler goroutine and test goroutine
  • Fix bodyFrom struct field comment to accurately describe dot-path semantics (including steps.<name>... support and JSON fallback for non-string/[]byte types)
  • Fix buildRequest() doc comment to clarify that rawBody means "raw (string/[]byte/nil) body, skip auto Content-Type"
  • All tests pass with -race flag
Original prompt

This section details on the original issue you should resolve

<issue_title>Feature: Add body_from config to step.http_call for raw body forwarding</issue_title>
<issue_description>## Problem

step.http_call currently supports two modes for the request body:

  1. Custom body map (body: {key: value}) — always JSON-marshaled via json.Marshal()
  2. Auto body from pc.Current — when no body config and method is not GET/HEAD, pc.Current is JSON-marshaled

Both modes force JSON serialization, which means:

  • Original request bodies cannot be forwarded as-is (e.g., webhook payloads, form data, XML)
  • Pre-constructed JSON strings get double-encoded
  • Binary data cannot be sent

Other step types like step.json_response and step.raw_response already support a body_from / _from pattern to inject raw values from step outputs. step.http_call should support the same pattern for consistency.

Proposed Solution

Add a body_from configuration key to step.http_call that specifies a dot-path in pc.Current to use as the raw request body, bypassing JSON marshaling.

Priority in buildBodyReader():

  1. If body_from is set → resolve the value from pc.Current and use it as-is (string → []byte, []byte → direct)
  2. If body map is set → JSON-marshal (existing behavior)
  3. If neither → JSON-marshal pc.Current for non-GET methods (existing behavior)

Example Configuration

steps:
  - name: parse
    type: step.request_parse
    config:
      parse_body: true

  - name: forward-webhook
    type: step.http_call
    config:
      url: "https://downstream-service.example.com/webhook"
      method: POST
      body_from: steps.parse.raw_body   # forward original body without re-serialization
      headers:
        Content-Type: "{{.steps.parse.headers.Content-Type}}"

Rationale

This is a low-risk addition that:

  • Follows the existing _from / body_from pattern used by response steps
  • Doesn't break existing behavior (only activates when body_from is explicitly configured)
  • Enables webhook relay, proxy, and passthrough use cases without custom steps
  • Complements a potential step.http_proxy step for simpler forwarding scenarios</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@intel352
Copy link
Contributor

intel352 commented Mar 2, 2026

@copilot try again

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 2, 2026

@copilot try again

Implemented in c52f9bf. The body_from feature is now working:

  • Added bodyFrom field to HTTPCallStep with config key body_from
  • buildBodyReader() checks body_from first (highest priority): string/[]byte values are forwarded raw; other types are JSON-marshaled; nil sends no body
  • buildRequest() skips auto-setting Content-Type: application/json for raw bodies (so you can set your own via headers)
  • Follows the same resolveBodyFrom() pattern used by step.json_response, step.raw_response, and step.auth_validate
  • 5 new tests added covering string, bytes, step output path, Content-Type override, and nil path scenarios

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copilot AI changed the title [WIP] Add body_from config to step.http_call for raw body forwarding Add body_from config to step.http_call for raw body forwarding Mar 2, 2026
@intel352 intel352 marked this pull request as ready for review March 2, 2026 21:50
Copilot AI review requested due to automatic review settings March 2, 2026 21:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds body_from support to the step.http_call pipeline step so request bodies can be forwarded without forced JSON re-encoding (enabling webhook passthrough, binary, XML, etc.), aligning behavior with existing _from/body_from patterns used in other steps.

Changes:

  • Extend HTTPCallStep with body_from configuration and update request body construction to optionally forward raw string/[]byte values.
  • Update request building to avoid auto-setting Content-Type: application/json when the body is forwarded in raw mode.
  • Add unit tests covering body_from behaviors (string, bytes, step output resolution, content-type override, nil/missing path).

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
module/pipeline_step_http_call.go Implements body_from resolution and raw-body handling for outgoing HTTP requests.
module/pipeline_step_http_call_test.go Adds test coverage for body_from forwarding and header behavior.
example/go.mod Updates example module dependencies (indirect).
example/go.sum Updates example module checksums to match dependency changes.

@intel352
Copy link
Contributor

intel352 commented Mar 2, 2026

@copilot apply changes based on the comments in this thread

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 2, 2026

@copilot apply changes based on the comments in this thread

Applied all three review changes in af9ed8d:

  1. Data race fixbody_from tests now use buffered channels to transfer captured values from the httptest handler goroutine to the test goroutine; all tests pass with -race
  2. bodyFrom field comment — updated to accurately describe that it supports steps.<name>... paths and that non-string/[]byte values fall back to JSON marshaling
  3. buildRequest() doc comment — updated to clarify that rawBody=true means the body is a raw string/[]byte/nil value and Content-Type should not be auto-set to application/json

@intel352 intel352 merged commit ad4542e into main Mar 2, 2026
14 checks passed
@intel352 intel352 deleted the copilot/add-body-from-config-http-call branch March 2, 2026 22:54
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.

Feature: Add body_from config to step.http_call for raw body forwarding

3 participants