Skip to content

Commit 768a74f

Browse files
authored
Plugin proxy – handle artifacts hosted on windows.net (#889)
Fixes an issue reported by @gziolo: > WordPress/gutenberg#57256 - I can’t preview this PR using Playground https://playground.wordpress.net/gutenberg.html. What do I miss? All CI checks are green. The culprit was that GitHub hosts that artifact on another domain: `productionresultssa0.blob.core.windows.net`. The current `file_get_contents` call follows the redirection URL and resends the same HTTP headers. That used to be fine, but now the windows.net host rejects those headers. This PR ensures we don't implicitly follow the 302 redirect, but parse the target URL and send an explicit request with a fresh set of HTTP headers. As a bonus, this makes the download much faster as we now use the `streamHttpResponse` function which immediately passes the response bytes back to the browser instead of buffering the entire response first. This PR also switches from HEAD-request-based PR validation to the same Query params–based one as the wordpress.html previewer uses. ## Testing instructions Try to preview the above PR in the Gutenberg PR previewer on https://playground.wordpress.net/gutenberg.html and confirm that it works now (this fix is already deployed).
1 parent 6302882 commit 768a74f

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

packages/playground/website/public/gutenberg.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
// Verify that the PR exists and that GitHub CI finished building it
118118
const zipArtifactUrl = `/plugin-proxy.php?org=WordPress&repo=gutenberg&workflow=Build%20Gutenberg%20Plugin%20Zip&artifact=gutenberg-plugin&pr=${prNumber}`;
119119
// Send the HEAD request to zipArtifactUrl to confirm the PR and the artifact both exist
120-
const response = await fetch(zipArtifactUrl, { method: 'HEAD' });
120+
const response = await fetch(zipArtifactUrl + '&verify_only=true');
121121
if (response.status !== 200) {
122122
errorDiv.innerText = `The PR ${prNumber} does not exist or GitHub CI did not finish building it yet.`;
123123
submitting = false;

packages/playground/website/public/plugin-proxy.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,23 @@ public function streamFromGithubPR($organization, $repo, $pr, $workflow_name, $a
108108
'vary',
109109
'cache-Control'
110110
);
111-
$artifact = $this->gitHubRequest($zip_download_api_endpoint, false);
112-
foreach ($artifact['headers'] as $header_line) {
111+
$artifact_res = $this->gitHubRequest($zip_download_api_endpoint, false, false);
112+
ob_end_flush();
113+
flush();
114+
115+
// The API endpoint returns the actual artifact URL as a 302 Location header.
116+
foreach ($artifact_res['headers'] as $header_line) {
113117
$header_name = strtolower(substr($header_line, 0, strpos($header_line, ':')));
114-
if (in_array($header_name, $allowed_headers)) {
115-
header($header_line);
118+
$header_value = trim(substr($header_line, 1 + strpos($header_line, ':')));
119+
if ($header_name === 'location') {
120+
streamHttpResponse($header_value, 'GET', [], NULL, $allowed_headers, [
121+
'Content-Type: application/zip',
122+
]);
123+
die();
116124
}
117125
}
118-
echo $artifact['body'];
119-
ob_flush();
120-
flush();
121-
return;
126+
127+
throw new ApiException('artifact_redirect_not_present');
122128
}
123129
if (!$artifacts) {
124130
throw new ApiException('artifact_not_available');
@@ -156,14 +162,15 @@ public function streamFromGithubReleases($repo, $name)
156162
}
157163
}
158164

159-
protected function gitHubRequest($url, $decode = true)
165+
protected function gitHubRequest($url, $decode = true, $follow_location = true)
160166
{
161167
$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36';
162168
$headers[] = 'Authorization: Bearer ' . $this->githubToken;
163169
$context = stream_context_create([
164170
'http' => [
165171
'method' => 'GET',
166172
'header' => implode("\r\n", $headers),
173+
'follow_location' => $follow_location
167174
]
168175
]);
169176
$response = file_get_contents($url, false, $context);

0 commit comments

Comments
 (0)