REST API: Always register the media url argument - #12833
Conversation
Sideloading an external image with the `url` parameter on `POST /wp/v2/media` works around a cross-origin fetch the browser cannot make. That fetch fails regardless of whether client-side media processing is enabled, so the argument was registered too narrowly. Leaving the argument unregistered did not disable it. `create_item()` reads the parameter either way, so on a site without client-side media processing the sideload still ran, but without the `sanitize_url` and `wp_http_validate_url()` callbacks the registered argument carries, and an unsafe URL returned a bare `http_request_failed` rather than a 400. Register `url` unconditionally so its validation always applies. The `generate_sub_sizes` and `convert_format` parameters are different: they hand image processing to the client, and the route the client uploads the results to is only registered when the feature is enabled. Honoring them otherwise would leave an attachment with no sub-sizes and no way to add them, and would relax the unsupported image type check in `create_item_permissions_check()` on a site that never opted in. Both are now ignored unless client-side media processing is enabled. Follow-up to [62659]. See #65517.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
I'm a little on the fence about this one. In terms of the REST API itself, for the behaviours of switching off conversion or generating sub-sizes, do we care if client-side media processing is enabled? Is whether client-side media processing is enabled orthogonal to the behaviour here? I don't mind too much either way, I'm mostly thinking about how to keep things simple. |
|
@adamsilverstein @andrewserong 👋🏻 Sorry for the late flag, I'm still wrapping my head around bits here. Here's my understanding of the paths that we're adding in 7.1. First, there is a new "Upload to Media Library" button in the editor that appears when you have image block markup like this: This submits a payload to the This can also be fired as part of a pre-publish check suggesting that external media be uploaded. Second, when a supported image is uploaded by the user in a supported browser and
And then third, as a side effect of adding those features, the ability for extenders to make calls to these endpoints:
Conclusions It seems like the WordPress core editor side of things is working as expected, but I think there are a handful of other things that can be cleaned up or clarified before folks discover the endpoints and start using them. It will be harder to correct in the future and maintain back-compat.
Items 2, 3, and 4 come from a lack of parity between |
That makes sense, we would want the usual |
Addresses @jeremyfelt's question in https://core.trac.wordpress.org/ticket/65517#comment:14 about
url,generate_sub_sizes, andconvert_formatbeing processed onPOST /wp/v2/mediaeven when they aren't registered in the schema.They needed fixing in opposite directions, which is what this does.
urlshould work either way. Sideloading an external image works around a cross-origin fetch the browser can't make, and that fails whether or not client side media processing is enabled - cross-origin isolation makes it necessary, not conditional. As far as I can tell the feature doesn't depend on client side media processing at all, so the argument is now registered unconditionally.Worth being clear that leaving it unregistered was never disabling it.
create_item()reads the parameter either way, so the sideload already ran on sites without the feature, just without thesanitize_urlandwp_http_validate_url()callbacks the registered argument carries. An unsafe URL came back as a barehttp_request_failedinstead of a 400. Registering it always is what actually closes that.generate_sub_sizesandconvert_formatgo the other way. They hand image processing to the client, and the/media/<id>/sideloadroute the client uploads the results to is only registered when the feature is on. Honoring them otherwise leaves an attachment with no sub-sizes and no way to add them, andgenerate_sub_sizesoffalsealso relaxes the unsupported image type check increate_item_permissions_check()on a site that never opted in. Both are now ignored unless client side media processing is enabled.Trac ticket: https://core.trac.wordpress.org/ticket/65808
How has this been tested
urlis registered while the other two aren't, sideloading works, an unsafe URL is rejected with a 400, andgenerate_sub_sizesoffalseis ignored so sub-sizes are still generated. Three of the four fail on trunk without the change - I checked by stashing the source change and re-running. The fourth is a regression guard, since the sideload already worked on trunk, just unvalidated.WP_Test_REST_Attachments_Controllerclass: 192 tests, 2 skipped, 0 failures.phpcs --standard=phpcs.xml.distclean on both changed files.wp-api-generated.jsneeds no update. The fixture is generated with client side media processing enabled, and in that configuration the registered arguments are unchanged.Types of changes
urlargument unconditionally inget_endpoint_args_for_item_schema().generate_sub_sizesandconvert_formatincreate_item()andcreate_item_permissions_check()unless client side media processing is enabled.disable_client_side_media_processing()test helper.Note on an existing test
test_upload_unsupported_image_type_skipped_when_not_generating_sub_sizes(from #64836) called the permissions check withgenerate_sub_sizesoffalsewithout enabling client side media processing, so it was asserting exactly the behavior this changes. It now enables the feature first, which keeps its original intent - the comment on it already says "when the client handles image processing" - but flagging it since it's an existing test from another ticket. @jeremyfelt @andrewserong does that read right to you?Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Drafting the implementation and tests from the review notes on the ticket. I reviewed and verified the behavior and test results myself.