Skip to content

feat(outcalls): CON-1636 enable support for PUT/DELETE in http_request - #8717

Merged
fspreiss merged 18 commits into
masterfrom
fspreiss/CON-1636-put-and-delete-in-http-request-phase-2
Mar 2, 2026
Merged

feat(outcalls): CON-1636 enable support for PUT/DELETE in http_request#8717
fspreiss merged 18 commits into
masterfrom
fspreiss/CON-1636-put-and-delete-in-http-request-phase-2

Conversation

@fspreiss

@fspreiss fspreiss commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Enables the support for PUT and DELETE in HTTP outcalls in non-replicated mode, which was prepared in #8715.

This is phase 2 of the two-phase rollout (see PR description of #8715): the release containing #8715 (see de43a37, which is currently running on the NNS subnet and which is based on 007c473 containing the PR here) was fully rolled out to all subnets, so it is safe to rollout a release containing this PR here.

This PR should be reviewed with the "Hide whitespace" option enabled.

@fspreiss
fspreiss requested a review from mihailjianu1 February 8, 2026 18:35
github-merge-queue Bot pushed a commit that referenced this pull request Feb 16, 2026
…st (#8715)

Prepares supporting the PUT and DELETE HTTP methods in HTTPS outcalls in
non-replicated mode.

In particular, this PR
* adds variants for PUT and DELETE in the various HTTP method enums
* adapts execution to disallow HTTP outcalls with the new methods
* adapts execution to allow PUT/DELETE only in non-replicated mode
* adds support for the new methods in HTTP outcalls adapter and verifies
this support through tests
* adds system tests ensuring that the new methods are currently
disallowed
* adds system tests, which are not yet enabled, ensuring that the new
methods are only allowed in non-replicated mode

### Rollback safety through two-phase rollout

Because the HTTP method is also part of the replicated state in the
respective call contexts (`CanisterHttpRequestContext`), the feature
cannot be enabled directly but needs to be rolled out in two stages:

* Stage 1 (this PR here): the replica will be able to read and process
contexts that have the new HTTP methods, but it will NOT put such
contexts in the replicated state. Rolling back a replica version with
this PR is safe because the replicated state is unchanged.
* Stage 2 ([ic/pull/8717](#8717)): the
replica now allows to make HTTP outcalls with PUT/DELETE, i.e., also
puts contexts with the new HTTP methods in the replicated state. Rolling
back a replica version at this stage is safe because the replica in the
previous stage is already able to read and process the new methods.

### Support in non-replicatd mode only

For now, we will support PUT/DELTE only in non-replicated mode to avoid
confusing race conditions that may occur. For example, if first a DELETE
outcall for resource R is made, directly followed by a PUT or POST
outcall for R, in replicated mode it may happen that R is actually
_deleted_ after the PUT/POST outcall has finished, because the IC does
_not_ necessarily wait for _all_ outcalls to complete before a result is
delivered back to the canister: The IC only waits for sufficient calls
to complete to reach consensus on the result.
Base automatically changed from fspreiss/CON-1636-put-and-delete-in-http-request to master February 16, 2026 20:23
kpop-dfinity pushed a commit that referenced this pull request Feb 20, 2026
…st (#8715)

Prepares supporting the PUT and DELETE HTTP methods in HTTPS outcalls in
non-replicated mode.

In particular, this PR
* adds variants for PUT and DELETE in the various HTTP method enums
* adapts execution to disallow HTTP outcalls with the new methods
* adapts execution to allow PUT/DELETE only in non-replicated mode
* adds support for the new methods in HTTP outcalls adapter and verifies
this support through tests
* adds system tests ensuring that the new methods are currently
disallowed
* adds system tests, which are not yet enabled, ensuring that the new
methods are only allowed in non-replicated mode

### Rollback safety through two-phase rollout

Because the HTTP method is also part of the replicated state in the
respective call contexts (`CanisterHttpRequestContext`), the feature
cannot be enabled directly but needs to be rolled out in two stages:

* Stage 1 (this PR here): the replica will be able to read and process
contexts that have the new HTTP methods, but it will NOT put such
contexts in the replicated state. Rolling back a replica version with
this PR is safe because the replicated state is unchanged.
* Stage 2 ([ic/pull/8717](#8717)): the
replica now allows to make HTTP outcalls with PUT/DELETE, i.e., also
puts contexts with the new HTTP methods in the replicated state. Rolling
back a replica version at this stage is safe because the replica in the
previous stage is already able to read and process the new methods.

### Support in non-replicatd mode only

For now, we will support PUT/DELTE only in non-replicated mode to avoid
confusing race conditions that may occur. For example, if first a DELETE
outcall for resource R is made, directly followed by a PUT or POST
outcall for R, in replicated mode it may happen that R is actually
_deleted_ after the PUT/POST outcall has finished, because the IC does
_not_ necessarily wait for _all_ outcalls to complete before a result is
delivered back to the canister: The IC only waits for sufficient calls
to complete to reach consensus on the result.
@fspreiss
fspreiss marked this pull request as ready for review March 2, 2026 15:22
@fspreiss
fspreiss requested review from a team as code owners March 2, 2026 15:22
@fspreiss
fspreiss added this pull request to the merge queue Mar 2, 2026
Merged via the queue into master with commit 6abb9ff Mar 2, 2026
43 of 44 checks passed
@fspreiss
fspreiss deleted the fspreiss/CON-1636-put-and-delete-in-http-request-phase-2 branch March 2, 2026 19:54
ggreif added a commit to ggreif/ic that referenced this pull request Jun 4, 2026
Per review on dfinity#10378: PATCH is plumbed through the types but must not enter
replicated state on any subnet until support has rolled out to all replicas
(mirroring the PUT/DELETE staging in dfinity#8715/dfinity#8717). Both `generate_from_args`
and `generate_from_flexible_args` now reject PATCH outright with a new
`CanisterHttpRequestContextError::HttpMethodNotYetSupported` ("The PATCH HTTP
method is not yet supported."), independent of `is_replicated`. A follow-up PR
enables it once the rollout completes.

Tests: PATCH dropped from the PUT/DELETE non-replicated/flexible cases; new
unit test `patch_is_rejected_until_rollout` covers both entry points; the
system test `test_patch_call` becomes `test_patch_rejected` and the
now-redundant `test_patch_without_non_replicated_rejected` is removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pull Bot pushed a commit to mikeyhodl/ic that referenced this pull request Jun 5, 2026
…dfinity#10378)

## What

Adds the `PATCH` HTTP method to canister HTTPS outcalls
(`http_request`), following the `PUT`/`DELETE` rollout in dfinity#8715 / dfinity#8717.

`PATCH` variants are added across every HTTP-method enum and conversion
in the outcall path:

- `ic_management_canister_types_private::HttpMethod` and the public
`ic-management-canister-types` `HttpMethod` (+ `tests/ic.did` candid +
fixture)
- `CanisterHttpMethod` (+ the `state.metadata.v1` protobuf enum, its
`.proto`, and the generated Rust)
- the `https_outcalls` service `.proto`, the adapter method mapping
(`rpc_server.rs`), and the client (`client.rs`)
- the pocket-ic REST `CanisterHttpMethod` and the pocket-ic-server
mapping

## Rejected in the execution layer until rollout

Per review, and following the staged approach from dfinity#8715: this PR
**plumbs** `PATCH` but does **not** enable it on replicated subnets yet.
`generate_from_args` and `generate_from_flexible_args` reject `PATCH`
outright with a new
`CanisterHttpRequestContextError::HttpMethodNotYetSupported` (*"The
PATCH HTTP method is not yet supported."*), independent of
`is_replicated`. This guarantees no `PATCH` `http_method` enters
replicated state before the variant is understood by all replicas
(avoiding cross-version deserialization / replay divergence during
rollout).

A follow-up PR removes the guard once the rollout is complete, at which
point `PATCH` behaves like `PUT`/`DELETE` — permitted only for
non-replicated / deterministic-response-count requests, since `PATCH` is
a non-idempotent mutation (RFC 5789 §2).

## Tests

- `canister_http.rs`: `patch_is_rejected_until_rollout` asserts `PATCH`
is rejected via both entry points; `PATCH` is dropped from the
`PUT`/`DELETE` cases in `put_delete_requires_non_replicated` and
`flexible_methods_require_deterministic_response_counts`; the
enum-stability assertion stays `[1, 2, 3, 4, 5, 6]`.
- `https_outcalls/adapter/tests/server_test.rs`:
`test_canister_http_server_patch` + a `/patch` route on the test server
(the adapter mapping is below the execution-layer guard, so it is
exercised directly).
- `rs/tests/networking/canister_http_correctness_test.rs`:
`test_patch_rejected` asserts a `PATCH` outcall is rejected.
- `httpbin-rs`: `/anything` gains a `PATCH` route.

## Notes for reviewers

- Staged rollout per @eichhorl: `PATCH` is plumbed but hard-rejected in
the execution layer; the enabling PR follows once the rollout is done.
- Built/validated by CI rather than locally.

Spec/docs companion: dfinity/portal#6245. Requested in
dfinity/portal#6244.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants