-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a shim to override wp.apiRequest, allowing HTTP/1.0 emulation #5741
Conversation
This is ready to merge, with review. It's been tested against a previously failing WAF. |
lib/compat.php
Outdated
var oldApiRequest = wp.apiRequest; | ||
wp.apiRequest = function ( options ) { | ||
if ( options.method ) { | ||
if( [ 'GET', 'PUT', 'DELETE' ].indexOf( options.method.toUpperCase() ) >= 0 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after if
is missing :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙃
|
||
$scripts->add_inline_script( 'wp-api-request', $api_request_fix, 'after' ); | ||
} | ||
add_action( 'wp_default_scripts', 'gutenberg_shim_api_request_emulate_http' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous shim was called inside gutenberg_editor_scripts_and_styles
. This code uses wp_default_scripts
action. Not sure what is the difference as I can't find what this action
does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No practical difference, I just copy/pasta-ed from the gutenberg_shim_fix_api_request_plain_permalinks
shim above it.
lib/compat.php
Outdated
var oldApiRequest = wp.apiRequest; | ||
wp.apiRequest = function ( options ) { | ||
if ( options.method ) { | ||
if ( [ 'GET', 'PUT', 'DELETE' ].indexOf( options.method.toUpperCase() ) >= 0 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I noticed which differs from Backbone:
(type === 'PUT' || type === 'DELETE' || type === 'PATCH')
https://github.com/jashkenas/backbone/blob/master/backbone.js#L1587
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested but I think it looks good. It would be the best idea to ask someone who has issues with the regular HTTP methods to confirm.
lib/compat.php
Outdated
if ( options.method ) { | ||
if ( [ 'PATCH', 'PUT', 'DELETE' ].indexOf( options.method.toUpperCase() ) >= 0 ) { | ||
if ( ! options.headers ) { | ||
options.headers = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be assigned as an object, not array.
http://api.jquery.com/jquery.ajax/ (settings.headers
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed that, but array is also an object in JS... so might work, but obviously should be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻
var oldApiRequest = wp.apiRequest; | ||
wp.apiRequest = function ( options ) { | ||
if ( options.method ) { | ||
if ( [ 'PATCH', 'PUT', 'DELETE' ].indexOf( options.method.toUpperCase() ) >= 0 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, we could inverse the check to better reflect that we support only GET
and POST
:
if ( [ 'GET', 'POST' ].indexOf( options.method.toUpperCase() ) === -1 ) {
Aside: Curiosity got me wondering: https://jsperf.com/indexof-array-vs-regexp (tl;dr: This is good)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OPTIONS
shouldn't be converted, either. (Neither should HEAD
, CONNECT
, or TRACE
, even though we don't specifically use them anywhere.) I'm inclined to go with the same conversion as Backbone, as that's the one that is most likely to be supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I'm not clear what exactly we're doing in this pull request then. Are we targeting HTTP/1.0 ? There are only 3 defined verbs (previously overlooked HEAD
):
https://www.w3.org/Protocols/HTTP/1.0/spec.html#Methods
It makes me a bit nervous that we target Backbone, as it's not obvious why we target Backbone (aside from anecdotal evidence that it appears to be well-supported).
var oldApiRequest = wp.apiRequest; | ||
wp.apiRequest = function ( options ) { | ||
if ( options.method ) { | ||
if ( [ 'PATCH', 'PUT', 'DELETE' ].indexOf( options.method.toUpperCase() ) >= 0 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I'm not clear what exactly we're doing in this pull request then. Are we targeting HTTP/1.0 ? There are only 3 defined verbs (previously overlooked HEAD
):
https://www.w3.org/Protocols/HTTP/1.0/spec.html#Methods
It makes me a bit nervous that we target Backbone, as it's not obvious why we target Backbone (aside from anecdotal evidence that it appears to be well-supported).
Not exactly. More like "simulate HTTP/1.0 for the HTTP/1.1 verbs that have problematic support".
Backbone just happens to be the previous implementation of the same thing, via the |
Hi, this issue is still occurring for me. I'm not a developer in any way, so if someone can help me troubleshoot, that would be really lovely. I have a SiteGround-hosted WordPress site; WP 5.0.2 and cannot update pages. I get the "Updating failed" error in the editor, and the following console errors in the Chrome Inspector: POST /wp-json/wp/v2/pages/1242?_locale=user 403 |
@jutta-livingmiracles I'm not sure this pull addresses the same issue you were experiencing because this old pull references I would recommend creating a new issue documenting your problems and it can be addressed there. Please make sure you can reproduce this without any themes/plugins active on your site as well. |
Description
#4396 switched API requests to using HTTP/1.0, using Backbone's
emulateHTTP
setting. #5253 changed to usingwp.apiRequests()
for API requests, which uses jQuery. Unfortunately, jQuery doesn't have a setting similar toemulateHTTP
, so we need to manually do it, instead.It seems that a lot of web application firewalls have stricter rules for
PUT
requests, so the merge of #5253 manifests itself as posts sporadically failing to save. For example: #5675, #5632, #5660.I've also opened a core ticket to address this behaviour.
How Has This Been Tested?
Using your browser's dev tools, watch the network requests, and confirm that the save request for a post is sent as a
POST
, with theX-HTTP-Method-Override: PUT
header. The post should save correctly.If you have a WAF that currently blocks saving posts in Gutenberg 2.4, this PR should fix that behaviour.
Checklist: