downshiftorg / prophoto-issues

Public issue tracking for ProPhoto 6
8 stars 8 forks source link

Improper wp_ajax_ handling #749

Closed kpumuk closed 7 years ago

kpumuk commented 7 years ago

Hi,

There is an issue with /wp-admin/admin-ajax.php actions ('wp_ajax_pp_api_' . $this->resource in BaseApiMiddleware). WordPress expects those actions to exit PHP process:

From https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)

add_action( 'wp_ajax_add_foobar', 'prefix_ajax_add_foobar' );

function prefix_ajax_add_foobar() {
    // Handle request then generate response using WP_Ajax_Response

    // Don't forget to stop execution afterward.
    wp_die();
}

Now, if you don't call die() or wp_die(), this line will be executed: https://github.com/WordPress/WordPress/blob/master/wp-admin/admin-ajax.php#L104

ProPhoto does not stop execution, it only sets response header and exits in lots of cases. Normally, that would not be a problem, but there is an edge case. HTTP response code 204 is being used to notify the client that no body should be expected. In the case of ProPhoto, status 204 is used for many actions, but the execution is not stopped, so the body with a single byte 0 is always rendered.

Again, it is only a small problem in most of the cases. Curl will report something like

Excess found in a non pipelined read: excess = 1 url = /wp-admin/admin-ajax.php?id=pp-menu-2&action=pp_api_widget (zero-length body)

But, if the site is using CloudFlare – that's the whole different story:

https://twitter.com/kpumuk/status/841292524740345856 https://twitter.com/kpumuk/status/841293410518614016

TLDR: If you return non-empty body with a 204 request, CloudFlare will sleep indefinitely on a request. It is up to the client on how long exactly the delay is. From my experience: XMLHttpRequest in Chrome will timeout in exactly 10 minutes (contact form with ProPhoto6, this is how we found the issue), normal HTTP request from Chrom is about 6 minutes delay, Curl will sleep for about 2 minutes (100 seconds).

So there are two sides of this issue: improper handling of ajax requests in ProPhoto6 (this is why I'm creating this ticket) and CloudFlare (they called this not an issue, but I will see if there is a way to make them reconsider).

brianium commented 7 years ago

@kpumuk thanks for opening this issue! Funny you should mention this - we noticed this problem just this morning with a customer's site and realized our error. We have already pushed a fix and it should be included in the next release :)