Fix Guzzle following redirects with a custom temporary sink
authorTim Düsterhus <duesterhus@woltlab.com>
Mon, 24 Aug 2020 08:46:36 +0000 (10:46 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Mon, 24 Aug 2020 08:51:02 +0000 (10:51 +0200)
When following redirects Guzzle copies over the request options for the next
iteration internally, including the bare `resource` that was passed to it.

This bare resource will then be wrapped into the Stream wrapper. This stream
wrapper explicitely calls `close()` for the underlying resource when it is
being closed.

The created Streams for the subrequests will be closed before the `send`
function returns, thus ultimately closing the resource for the “parent”
request.

Fix this issue by passing a Stream, instead of a bare resource. This one
will be passed along as-is.

Fixes #3529.

wcfsetup/install/files/lib/system/style/FontManager.class.php
wcfsetup/install/files/lib/util/HTTPRequest.class.php

index bfbe2ff5896fc82d789c453281218aa1d0c4a641..d9bbd95b793bde2c4cef7acf2f6fa1648a0fd408 100644 (file)
@@ -88,7 +88,7 @@ class FontManager extends SingletonFactory {
                                
                                $response = $this->http->send(new Request('GET', $family.'/'.$filename), [
                                        // https://github.com/guzzle/guzzle/issues/2735
-                                       'sink' => fopen("php://temp", "w+"),
+                                       'sink' => \GuzzleHttp\Psr7\stream_for(fopen("php://temp", "w+")),
                                ]);
                                
                                $file = new AtomicWriter($familyDirectory.'/'.$filename);
index 808f39ce777403af8e610024fcbbd95899c13f85..e0eb6a22242b32df7684fbc3c56574cb7b5c2e6e 100644 (file)
@@ -192,7 +192,7 @@ final class HTTPRequest {
                try {
                        $this->response = $client->send($request, [
                                // https://github.com/guzzle/guzzle/issues/2735
-                               'sink' => fopen("php://temp", "w+"),
+                               'sink' => \GuzzleHttp\Psr7\stream_for(fopen("php://temp", "w+")),
                        ]);
                }
                catch (TooManyRedirectsException $e) {