Increase HTTP request timeout to 60 seconds - #1407
Merged
gcsecsey merged 3 commits intoMay 20, 2025
Merged
Conversation
gcsecsey
marked this pull request as ready for review
May 16, 2025 16:34
nightnei
reviewed
May 19, 2025
epeicher
approved these changes
May 19, 2025
Member
Author
Thanks for patiently reviewing this @epeicher and sorry for the typo there. 😅 |
gcsecsey
deleted the
stu-323-feature-request-plugin-updater-setting-to-fix-timeout
branch
May 20, 2025 09:30
bcotrim
pushed a commit
that referenced
this pull request
May 27, 2025
* Increase HTTP request timeout to 60 seconds * Increase curl timeout to 60 seconds * update comments
bcotrim
added a commit
that referenced
this pull request
May 27, 2025
commit d31733b Author: katinthehatsite <katerynakodonenko@gmail.com> Date: Tue May 27 09:12:55 2025 +0200 Studio: Delete old proof-of-concept WP-CLI implementation (#1426) * Remove old scripts * Remove old cli.ts * Cleanup tests * Clean up terminal opening and feature flag * Cleanup assistant code * Clean shortcuts code * Cleanup feature flags * Cleanup feature flags * Cleanup shortcuts sessions * Removed unused feature flag for assistant * Assistant code block test fix * Adjust preload * Cleanup index file and tests * Refactor terminal usage * Add back the lock * Remove unintended change * Remove unnecesary type for warp * Use bundled Ids * Cleanup event parameter --------- Co-authored-by: Kateryna Kodonenko <kateryna@automattic.com> commit 4fac446 Author: Volodymyr Makukha <nei.css@gmail.com> Date: Mon May 26 20:19:35 2025 +0100 Update Ukrainian translations - May 26 (#1439) commit c7536ef Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Mon May 26 18:34:28 2025 +0100 Load LTR and RTL stylesheets conditionally (#1429) * Add a new component * Load @wordpress/components css conditionally based on RTL and LTR. * Load index.css a.k.a main_window.css after loading the WordPress stylesheet commit c80b70e Author: Bero <berislav.grgicak@gmail.com> Date: Mon May 26 19:20:42 2025 +0200 Update Playground packages to 1.0.38 and remove the Symlink manager (#1425) * Update Playground packages to 1.0.38 * Remove SymlinkManager * Activate Playground's followSymlinks feature * Remove @php-wasm/universal patch commit 5bfe676 Author: Wojtek Naruniec <wojtek.naruniec@automattic.com> Date: Mon May 26 15:40:18 2025 +0200 Sanitize regex in Win editor path (#1411) * Sanitize regex * Import only escapeRegExp function commit 2cd3e44 Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Mon May 26 13:18:02 2025 +0200 Bump version from 1.5.2-beta4 to 1.5.2 (#1436) commit f16865e Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Mon May 26 12:38:24 2025 +0200 Add release notes for 1.5.2 (#1434) * Add release notes for 1.5.2 * Reorder release notes * Update release notes order and formatting * Added latest UI fix to the release notes * Consolidate Studio CLI fixes into a single bullet point commit f6e48d5 Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Mon May 26 12:21:30 2025 +0200 Add translations for 1.5.2 (#1433) * Add translations for 1.5.2 * Add latest Polish and Spanish translations * Update spanish translations --------- Co-authored-by: Antonio Sejas <antonio@sejas.es> commit ae1d163 Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Mon May 26 10:58:22 2025 +0100 Share same styles between preview and sync tabs (#1435) commit d6a7905 Author: Roberto Aranda <roberto.aranda@automattic.com> Date: Fri May 23 15:23:14 2025 +0200 Return original URL param when it cannot be parsed (#1420) * Return the passed URL parameter when it cannot be parsed instead of an empty string commit 91d04be Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Fri May 23 14:22:34 2025 +0100 Update localized docs links for Studio Sync and Studio CLI (#1431) * Add translation link to new Spanish studio docs CLI * Add hash to Studio sync supported sites commit 6213094 Author: katinthehatsite <katerynakodonenko@gmail.com> Date: Fri May 23 14:27:53 2025 +0200 Add patch to fix the accessibility with modals (#1423) Co-authored-by: Kateryna Kodonenko <kateryna@automattic.com> commit b2724c0 Author: Rahul Gavande <rahul.gavande@automattic.com> Date: Fri May 23 14:45:11 2025 +0530 Use uri scheme to open Warp terminal app (#1428) commit 43c831b Author: Fredrik Rombach Ekelund <fredrik@f26d.dev> Date: Wed May 21 16:10:40 2025 +0200 CLI: Set UTF8 encoding for output on Windows (#1424) commit b1c0eeb Author: Volodymyr Makukha <nei.css@gmail.com> Date: Wed May 21 10:34:47 2025 +0100 Fix hiding plugins spinner (#1419) commit 48988ed Author: Fredrik Rombach Ekelund <fredrik@f26d.dev> Date: Wed May 21 10:31:33 2025 +0200 Add migration to rename launch uniques stat (#1415) * Add migration to rename launch uniques stat * Fix CLI zod schema commit f363144 Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Tue May 20 18:24:00 2025 +0200 Bump version to 1.5.2-beta4 (#1421) commit 9768e67 Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Tue May 20 15:29:33 2025 +0200 Pressable Sync: Fix remaining Sync modal issues (#1416) * Use absolute path for `WordPressLogoCircle` import * Use separate `isDisabled` to makde WP logo gray * Remove trailing space in site selector helper text * Decrease font size of sync sites modal learn more link commit 9fab398 Author: Ian G. Maia <iangmaia@users.noreply.github.com> Date: Tue May 20 13:15:23 2025 +0200 [Tooling] Update code to DRY the Windows build PS1 (#1408) * Update code to DRY the Windows build PS1 * Update case of `Exit` command * Use `windows` instead of just `win` to prefix windows-related scripts * Add $LastExitCode check after `npm run make` commit e5d4006 Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Tue May 20 12:01:21 2025 +0200 Improve version comparison logic to handle prerelease transitions correctly (#1403) commit f0a282b Author: Rahul Gavande <rahul.gavande@automattic.com> Date: Tue May 20 15:15:25 2025 +0530 HTTPS: Convert domain name Unicode characters to ASCII characters (#1400) * Convert domain name unicode chars to ASCII * Do not use punnycode domain name for paths * Remove unncessary punnycode domain name commit 6cdc351 Author: Roberto Aranda <roberto.aranda@automattic.com> Date: Tue May 20 11:35:52 2025 +0200 Sync: Update notification to include Hostname (#1412) * Push: Update notification to include Hostname * Pull: Update notification to include hostname * Add hints for translators commit 69419a6 Author: Gergely Csécsey <gergely.csecsey@automattic.com> Date: Tue May 20 10:30:57 2025 +0100 Increase HTTP request timeout to 60 seconds (#1407) * Increase HTTP request timeout to 60 seconds * Increase curl timeout to 60 seconds * update comments commit 6bcbbff Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Tue May 20 09:36:18 2025 +0100 Update connect site text button when connecting another site (#1413) * Adapt the "Connect Site" button when connecting multiple sites on Sync. commit 60a9cab Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Tue May 20 09:10:37 2025 +0100 Avoid orphan in sync title (#1414) commit 3b103cc Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Mon May 19 10:39:12 2025 +0100 Release 1.5.2-beta3 (#1410) commit a109671 Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Mon May 19 09:45:17 2025 +0200 Sync: Update sync tab text and remove WordPress logo from title (#1405) * Update sync tab text and remove WordPress logo from title * Fix related test * Use comma * Update copy of the bullet points * Replace `WP.com` with `WordPress.com`. Co-authored-by: Antonio Sejas <antonio.sejas@automattic.com> * Replace WP.com with WordPress.com Co-authored-by: Antonio Sejas <antonio.sejas@automattic.com> * Delete unused WordPress short logo component --------- Co-authored-by: Antonio Sejas <antonio.sejas@automattic.com> commit 716bc7a Author: Ivan Ottinger <ivan.ottinger@automattic.com> Date: Fri May 16 16:15:16 2025 +0200 Sync: Update Sync modal content (#1406) * Update WordPress logo component `viewBox` * Update Sync modal heading * Update text below Sync search field * Update Sync modal site logos * Replace hardcoded arrows with `ArrowIcon` component in sync sites modal links * Localize sync modal Read more link using `getLocalizedLink` utility commit 11b4302 Author: Roberto Aranda <roberto.aranda@automattic.com> Date: Fri May 16 15:14:40 2025 +0200 Push: Read and update the progress from the sync endpoint (#1389) * Calls the GET /sync/import using the importId to obtain the progress * Use the progress from the /sync/import endpoint to update the progress in the importing state * Splits the progress of the importing state between backup and import commit 7423bdf Author: katinthehatsite <katerynakodonenko@gmail.com> Date: Fri May 16 11:40:18 2025 +0200 Studio: Fix no directory or file error on Windows (#1391) * Fix no directory or file error on Windows * Cleanup directories --------- Co-authored-by: Kateryna Kodonenko <kateryna@automattic.com> commit 1661ac4 Author: Antonio Sejas <antonio.sejas@automattic.com> Date: Fri May 16 10:04:32 2025 +0100 Force display of what's new for minor version (#1404) * Force what's new display for minor version * Skip test that compares the patch version
1 task
chubes4
added a commit
to chubes4/studio
that referenced
this pull request
Apr 16, 2026
…imeout) Fixes Automattic#3118. The mu-plugin injected into every Studio site by getStandardMuPlugins sets CURLOPT_LOW_SPEED_LIMIT=1024 + CURLOPT_LOW_SPEED_TIME=30, aborting any outbound HTTP request where transfer rate stays below 1 KB/s for 30 consecutive seconds. These values were correct for the original motivation (plugin/theme downloads, Automattic#1407/Automattic#1913) -- a dead mirror delivering zero bytes is a broken connection, and aborting fast is the right behavior. They are incorrect for AI API requests, now a common Studio use case for plugin developers building on top of OpenAI, Anthropic, Google, etc. Non-streaming wp_remote_post calls to LLM providers produce zero bytes on the socket until the model emits its first token. On flagship models with long prompts, that first token commonly takes 30 to 90 seconds to arrive. The watchdog fires before content is delivered and aborts with cURL error 28 ("Operation too slow"). Raise CURLOPT_LOW_SPEED_TIME from 30 seconds to 120 seconds. All other thresholds unchanged, including the 300-second http_request_timeout outer cap. A working plugin download produces far more than 1 KB/s throughout its lifetime, so the low-speed watchdog never triggers for that use case -- the Automattic#1913 Jetpack-on-3G test passes identically. Dead-connection detection still works; it takes 120 seconds to detect instead of 30, which is a small DX regression for an uncommon failure mode, and the 300-second outer cap still catches fully hung requests. The only observable behavior change: AI API requests that would have died at 30 seconds now complete normally (up to the 300-second outer cap, which is already enough for all current flagship models). Reproduced cURL 28 aborts from Data Machine's daily memory compaction against api.openai.com with gpt-5.4 on a ~30 KB prompt. Built the CLI locally, verified the compiled mu-plugin contains the new value via PHP reflection on the runtime closure (CURLOPT_LOW_SPEED_TIME = 120), re-ran the compaction task against the same flagship model on the same site, and confirmed end-to-end completion. AI assistance: I used Claude Code to research the history of this mu-plugin (tracing through Automattic#1407 and Automattic#1913), evaluate the side effects of each possible adjustment (raising the time vs. lowering the limit vs. an escape-hatch filter), and draft this commit message and the accompanying PR body. The engineering decision to raise the time threshold to 120 seconds (rather than add a filter or discriminate by URL) was mine after reviewing the options. I verified the fix end-to-end against a live Studio site and the original reproduction.
This was referenced Apr 16, 2026
chubes4
added a commit
to chubes4/studio
that referenced
this pull request
Apr 17, 2026
…imeout) Fixes Automattic#3118. The mu-plugin injected into every Studio site by getStandardMuPlugins sets CURLOPT_LOW_SPEED_LIMIT=1024 + CURLOPT_LOW_SPEED_TIME=30, aborting any outbound HTTP request where transfer rate stays below 1 KB/s for 30 consecutive seconds. These values were correct for the original motivation (plugin/theme downloads, Automattic#1407/Automattic#1913) -- a dead mirror delivering zero bytes is a broken connection, and aborting fast is the right behavior. They are incorrect for AI API requests, now a common Studio use case for plugin developers building on top of OpenAI, Anthropic, Google, etc. Non-streaming wp_remote_post calls to LLM providers produce zero bytes on the socket until the model emits its first token. On flagship models with long prompts, that first token commonly takes 30 to 90 seconds to arrive. The watchdog fires before content is delivered and aborts with cURL error 28 ("Operation too slow"). Raise CURLOPT_LOW_SPEED_TIME from 30 seconds to 120 seconds. All other thresholds unchanged, including the 300-second http_request_timeout outer cap. A working plugin download produces far more than 1 KB/s throughout its lifetime, so the low-speed watchdog never triggers for that use case -- the Automattic#1913 Jetpack-on-3G test passes identically. Dead-connection detection still works; it takes 120 seconds to detect instead of 30, which is a small DX regression for an uncommon failure mode, and the 300-second outer cap still catches fully hung requests. The only observable behavior change: AI API requests that would have died at 30 seconds now complete normally (up to the 300-second outer cap, which is already enough for all current flagship models). Reproduced cURL 28 aborts from Data Machine's daily memory compaction against api.openai.com with gpt-5.4 on a ~30 KB prompt. Built the CLI locally, verified the compiled mu-plugin contains the new value via PHP reflection on the runtime closure (CURLOPT_LOW_SPEED_TIME = 120), re-ran the compaction task against the same flagship model on the same site, and confirmed end-to-end completion. AI assistance: I used Claude Code to research the history of this mu-plugin (tracing through Automattic#1407 and Automattic#1913), evaluate the side effects of each possible adjustment (raising the time vs. lowering the limit vs. an escape-hatch filter), and draft this commit message and the accompanying PR body. The engineering decision to raise the time threshold to 120 seconds (rather than add a filter or discriminate by URL) was mine after reviewing the options. I verified the fix end-to-end against a live Studio site and the original reproduction.
chubes4
added a commit
to chubes4/studio
that referenced
this pull request
Apr 20, 2026
…imeout) Fixes Automattic#3118. The mu-plugin injected into every Studio site by getStandardMuPlugins sets CURLOPT_LOW_SPEED_LIMIT=1024 + CURLOPT_LOW_SPEED_TIME=30, aborting any outbound HTTP request where transfer rate stays below 1 KB/s for 30 consecutive seconds. These values were correct for the original motivation (plugin/theme downloads, Automattic#1407/Automattic#1913) -- a dead mirror delivering zero bytes is a broken connection, and aborting fast is the right behavior. They are incorrect for AI API requests, now a common Studio use case for plugin developers building on top of OpenAI, Anthropic, Google, etc. Non-streaming wp_remote_post calls to LLM providers produce zero bytes on the socket until the model emits its first token. On flagship models with long prompts, that first token commonly takes 30 to 90 seconds to arrive. The watchdog fires before content is delivered and aborts with cURL error 28 ("Operation too slow"). Raise CURLOPT_LOW_SPEED_TIME from 30 seconds to 120 seconds. All other thresholds unchanged, including the 300-second http_request_timeout outer cap. A working plugin download produces far more than 1 KB/s throughout its lifetime, so the low-speed watchdog never triggers for that use case -- the Automattic#1913 Jetpack-on-3G test passes identically. Dead-connection detection still works; it takes 120 seconds to detect instead of 30, which is a small DX regression for an uncommon failure mode, and the 300-second outer cap still catches fully hung requests. The only observable behavior change: AI API requests that would have died at 30 seconds now complete normally (up to the 300-second outer cap, which is already enough for all current flagship models). Reproduced cURL 28 aborts from Data Machine's daily memory compaction against api.openai.com with gpt-5.4 on a ~30 KB prompt. Built the CLI locally, verified the compiled mu-plugin contains the new value via PHP reflection on the runtime closure (CURLOPT_LOW_SPEED_TIME = 120), re-ran the compaction task against the same flagship model on the same site, and confirmed end-to-end completion. AI assistance: I used Claude Code to research the history of this mu-plugin (tracing through Automattic#1407 and Automattic#1913), evaluate the side effects of each possible adjustment (raising the time vs. lowering the limit vs. an escape-hatch filter), and draft this commit message and the accompanying PR body. The engineering decision to raise the time threshold to 120 seconds (rather than add a filter or discriminate by URL) was mine after reviewing the options. I verified the fix end-to-end against a live Studio site and the original reproduction.
chubes4
added a commit
to chubes4/studio
that referenced
this pull request
Apr 23, 2026
…imeout) Fixes Automattic#3118. The mu-plugin injected into every Studio site by getStandardMuPlugins sets CURLOPT_LOW_SPEED_LIMIT=1024 + CURLOPT_LOW_SPEED_TIME=30, aborting any outbound HTTP request where transfer rate stays below 1 KB/s for 30 consecutive seconds. These values were correct for the original motivation (plugin/theme downloads, Automattic#1407/Automattic#1913) -- a dead mirror delivering zero bytes is a broken connection, and aborting fast is the right behavior. They are incorrect for AI API requests, now a common Studio use case for plugin developers building on top of OpenAI, Anthropic, Google, etc. Non-streaming wp_remote_post calls to LLM providers produce zero bytes on the socket until the model emits its first token. On flagship models with long prompts, that first token commonly takes 30 to 90 seconds to arrive. The watchdog fires before content is delivered and aborts with cURL error 28 ("Operation too slow"). Raise CURLOPT_LOW_SPEED_TIME from 30 seconds to 120 seconds. All other thresholds unchanged, including the 300-second http_request_timeout outer cap. A working plugin download produces far more than 1 KB/s throughout its lifetime, so the low-speed watchdog never triggers for that use case -- the Automattic#1913 Jetpack-on-3G test passes identically. Dead-connection detection still works; it takes 120 seconds to detect instead of 30, which is a small DX regression for an uncommon failure mode, and the 300-second outer cap still catches fully hung requests. The only observable behavior change: AI API requests that would have died at 30 seconds now complete normally (up to the 300-second outer cap, which is already enough for all current flagship models). Reproduced cURL 28 aborts from Data Machine's daily memory compaction against api.openai.com with gpt-5.4 on a ~30 KB prompt. Built the CLI locally, verified the compiled mu-plugin contains the new value via PHP reflection on the runtime closure (CURLOPT_LOW_SPEED_TIME = 120), re-ran the compaction task against the same flagship model on the same site, and confirmed end-to-end completion. AI assistance: I used Claude Code to research the history of this mu-plugin (tracing through Automattic#1407 and Automattic#1913), evaluate the side effects of each possible adjustment (raising the time vs. lowering the limit vs. an escape-hatch filter), and draft this commit message and the accompanying PR body. The engineering decision to raise the time threshold to 120 seconds (rather than add a filter or discriminate by URL) was mine after reviewing the options. I verified the fix end-to-end against a live Studio site and the original reproduction.
chubes4
added a commit
to chubes4/studio
that referenced
this pull request
May 29, 2026
…imeout) Fixes Automattic#3118. The mu-plugin injected into every Studio site by getStandardMuPlugins sets CURLOPT_LOW_SPEED_LIMIT=1024 + CURLOPT_LOW_SPEED_TIME=30, aborting any outbound HTTP request where transfer rate stays below 1 KB/s for 30 consecutive seconds. These values were correct for the original motivation (plugin/theme downloads, Automattic#1407/Automattic#1913) -- a dead mirror delivering zero bytes is a broken connection, and aborting fast is the right behavior. They are incorrect for AI API requests, now a common Studio use case for plugin developers building on top of OpenAI, Anthropic, Google, etc. Non-streaming wp_remote_post calls to LLM providers produce zero bytes on the socket until the model emits its first token. On flagship models with long prompts, that first token commonly takes 30 to 90 seconds to arrive. The watchdog fires before content is delivered and aborts with cURL error 28 ("Operation too slow"). Raise CURLOPT_LOW_SPEED_TIME from 30 seconds to 120 seconds. All other thresholds unchanged, including the 300-second http_request_timeout outer cap. A working plugin download produces far more than 1 KB/s throughout its lifetime, so the low-speed watchdog never triggers for that use case -- the Automattic#1913 Jetpack-on-3G test passes identically. Dead-connection detection still works; it takes 120 seconds to detect instead of 30, which is a small DX regression for an uncommon failure mode, and the 300-second outer cap still catches fully hung requests. The only observable behavior change: AI API requests that would have died at 30 seconds now complete normally (up to the 300-second outer cap, which is already enough for all current flagship models). Reproduced cURL 28 aborts from Data Machine's daily memory compaction against api.openai.com with gpt-5.4 on a ~30 KB prompt. Built the CLI locally, verified the compiled mu-plugin contains the new value via PHP reflection on the runtime closure (CURLOPT_LOW_SPEED_TIME = 120), re-ran the compaction task against the same flagship model on the same site, and confirmed end-to-end completion. AI assistance: I used Claude Code to research the history of this mu-plugin (tracing through Automattic#1407 and Automattic#1913), evaluate the side effects of each possible adjustment (raising the time vs. lowering the limit vs. an escape-hatch filter), and draft this commit message and the accompanying PR body. The engineering decision to raise the time threshold to 120 seconds (rather than add a filter or discriminate by URL) was mine after reviewing the options. I verified the fix end-to-end against a live Studio site and the original reproduction.
fredrikekelund
added a commit
that referenced
this pull request
Jul 7, 2026
…imeout) (#3120) ## Related issues Fixes #3118. ## Proposed Changes - Raise `CURLOPT_LOW_SPEED_TIME` from 30 seconds to 120 seconds in `getStandardMuPlugins`' `0-http-request-timeout.php`. - Update the inline documentation to explain the new threshold and the AI-API-request use case. - No other thresholds changed: `CURLOPT_CONNECTTIMEOUT` stays at 30s, `CURLOPT_LOW_SPEED_LIMIT` stays at 1024 B/s, `http_request_timeout` stays at 300s. ## Background The `0-http-request-timeout.php` mu-plugin was introduced in #1407 (May 2025, hard 60s timeout) and refined in #1913 (October 2025, replaced hard timeout with progress-based watchdog). Both PRs were correct for their motivation: plugin/theme downloads on slow connections. The #1913 design — abort if transfer stays below 1 KB/s for 30 consecutive seconds — fails fast on dead mirrors while letting working slow downloads (Jetpack 33 MB on 3G) complete. Since October 2025, AI-powered WordPress plugins (Data Machine, Intelligence, and others) have become a common Studio use case. Non-streaming `wp_remote_post` calls to LLM providers produce zero bytes on the socket until the model emits its first token. On flagship models with long prompts, that first token commonly takes 30 to 90 seconds. The watchdog fires before any content is delivered, aborting with cURL error 28. See #3118 for the full reproduction and context. ## Side effects of the change | Use case | Before (30s) | After (120s) | |---|---|---| | Plugin/theme download on fast internet | works | works | | Plugin/theme download on slow internet (Jetpack-on-3G test from #1913) | works (bytes flow >1 KB/s) | works (same) | | Dead mirror (0 B/s forever) | aborts in 30s | aborts in 120s | | Hung connection (bytes delivered, then stall) | aborts 30s after stall | aborts 120s after stall | | AI API request with <30s TTFB | works | works | | **AI API request with 30-120s TTFB** | **aborts with cURL 28** | **works** | | AI API request with >120s TTFB | aborts | aborts via 300s `http_request_timeout` outer cap | The only observable behavior change: AI API requests that were dying now complete. The only regression is that a truly hung connection takes 90 seconds longer to detect. The 300-second outer cap still catches fully broken requests. This is a small DX trade-off for an uncommon failure mode, in exchange for first-class AI API support. No new escape-hatch filter, no URL-based discrimination, no new configuration knob. The one default value moves to a number that makes both use cases work. ## Testing Instructions ### Existing #1913 regression test (plugin download on throttled connection) Per Bernardo's original methodology: 1. Install Network Link Conditioner (from Apple's Additional Tools for Xcode) 2. Set throttling to a slow profile (e.g., \"3G\" or \"Edge\") 3. In Studio, navigate to `/wp-admin/plugin-install.php` 4. Install the Jetpack plugin (33 MB) 5. Expected: completes successfully on throttled connection (may take several minutes) Should pass identically before and after this change — the slow-but-working download produces far more than 1 KB/s throughout, so the low-speed watchdog never triggers regardless of whether the threshold is 30s or 120s. ### New test case (slow-TTFB AI API request) 1. Install a plugin that uses `wp_remote_post` to call `https://api.openai.com/v1/chat/completions` (e.g., Data Machine or any ai-http-client consumer). 2. Configure it to use a flagship OpenAI model (`gpt-5.4` or similar). 3. Send a non-streaming request with a large prompt (~20 KB system prompt + long user message designed to trigger reasoning). 4. Expected before: fails with cURL error 28 (\"Operation too slow. Less than 1024 bytes/sec transferred during the last 30 seconds\") on requests where OpenAI's TTFB exceeds 30 seconds. 5. Expected after: completes normally for any TTFB up to 120 seconds; fails via the 300s outer cap beyond that. ### Dead-connection regression test 1. `wp eval 'var_dump(wp_remote_get(\"https://example.invalid/never-responds\"));'` 2. Expected: times out in approximately 30s (connect phase — not affected by this change). For a case that reaches the low-speed watchdog specifically, you'd need a server that accepts the connection but then sends zero bytes indefinitely (uncommon). That case would now take 120s to detect instead of 30s. ### Verifying the change is live in WASM ```php // Run via wp eval on a Studio site after restarting it: global $wp_filter; foreach ( $wp_filter['http_api_curl']->callbacks as $prio => $cbs ) { foreach ( $cbs as $cb ) { if ( $cb['function'] instanceof Closure ) { $r = new ReflectionFunction( $cb['function'] ); $f = $r->getFileName(); $lines = file( $f ); echo implode( '', array_slice( $lines, $r->getStartLine() - 1, $r->getEndLine() - $r->getStartLine() + 1 ) ); } } } ``` Expected output after restart should include `CURLOPT_LOW_SPEED_TIME, 120`. ## What this isn't - **Not an escape-hatch filter.** Shouldn't require opt-in. Defaults should just work for both use cases. - **Not URL discrimination.** No hardcoded list of AI endpoints. - **Not removing the mu-plugin.** #1913's protection is legitimate; this tunes it. - **Not touching the 300s outer cap.** Untouched. Separate concern if ever raised. ## AI assistance disclosure Per WordPress's [AI Guidelines](https://make.wordpress.org/ai/handbook/ai-guidelines/), disclosing meaningful AI assistance on this contribution: - I used Claude Code to research the history of the mu-plugin (tracing through #1407 and #1913), evaluate the side effects of possible adjustments (raising the time vs. lowering the limit vs. an escape-hatch filter), and draft the commit message and PR body. - The engineering decision (raise time threshold to 120s rather than add a filter or discriminate by URL) was mine after reviewing the options with Claude Code. - I tested the fix end-to-end on a live Studio site running the Data Machine plugin, including verifying the compiled mu-plugin contains the new value via PHP reflection on the runtime closure, and re-running the daily memory compaction task against flagship gpt-5.4 to confirm completion. - The original cURL 28 reproduction that motivated this fix was observed during real Data Machine usage earlier in the same session. All substantive design decisions and the testing were my own; AI was used for investigation, pattern recognition, and drafting. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? Co-authored-by: Fredrik Rombach Ekelund <fredrik.rombach.ekelund@automattic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Related issues
Fixes STU-323 Feature Request: Plugin Updater Setting (to Fix Timeout)
Proposed Changes
This PR addresses timeout issues with plugin updates by increasing the default HTTP request timeout to 60 seconds.
0-http-request-timeout.phpthat sets the default HTTP request timeout and curl timeouts to 60 secondsTesting Instructions
npm startfunctions.phpof the active theme, and add this snippet:wp-now.ts, and kill and restart StudioPre-merge Checklist