PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.2
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.2
16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / vendor / wp-php-toolkit / http-client / ByteStream / class-seekablerequestreadstream.php
jetpack / vendor / wp-php-toolkit / http-client / ByteStream Last commit date
class-chunkeddecoderreadstream.php 6 days ago class-chunkedencoderbytetransformer.php 6 days ago class-requestreadstream.php 6 days ago class-seekablerequestreadstream.php 6 days ago
class-seekablerequestreadstream.php
134 lines
1 <?php
2
3 namespace WordPress\HttpClient\ByteStream;
4
5 use WordPress\ByteStream\FileReadWriteStream;
6 use WordPress\ByteStream\ReadStream\BaseByteReadStream;
7 use WordPress\ByteStream\ReadStream\ByteReadStream;
8 use WordPress\HttpClient\Request;
9
10 /**
11 * HTTP reader that can seek() within the stream.
12 *
13 * Downloaded bytes are stored in a temporary file. All the read operations are delegated to that file.
14 *
15 * – Seek()-ing forward is done by fetching all the bytes up to the target offset.
16 * – Seek()-ing backwards is done by seeking within the temporary file.
17 */
18 class SeekableRequestReadStream implements ByteReadStream {
19
20
21 /**
22 * RequestReadStream
23 */
24 private $remote;
25 /**
26 * FileReadWriteStream
27 */
28 private $cache;
29 private $temp;
30 private $length_resolved = false;
31
32 public function __construct( $request, array $options = array() ) {
33 if ( is_string( $request ) ) {
34 $request = new Request( $request );
35 }
36 $this->remote = new RequestReadStream( $request, $options );
37 $this->temp = $options['cache_path'] ?? tempnam( sys_get_temp_dir(), 'wp_http_cache_' );
38 $this->cache = FileReadWriteStream::from_path( $this->temp, true );
39 }
40
41 private function pipe_until( int $offset ): void {
42 while ( null === $this->cache->length() || $this->cache->length() < $offset ) {
43 $pulled = $this->remote->pull( BaseByteReadStream::CHUNK_SIZE_BYTES );
44 if ( 0 === $pulled ) {
45 break;
46 }
47 $this->cache->append_bytes( $this->remote->consume( $pulled ) );
48 }
49 }
50
51 public function length(): ?int {
52 if ( ! $this->length_resolved && null === $this->remote->length() ) {
53 /**
54 * Wait for the remote headers before returning the length.
55 *
56 * This is an inconsistency between RequestReadStream::length():
57 *
58 * * RequestReadStream returns null until the remote headers are known.
59 * * SeekableRequestReadStream proactively waits for the remote headers.
60 *
61 * That's because:
62 *
63 * * RequestReadStream class is a lower-level utility where we simply
64 * expose what's available at the moment. The developer is responsible
65 * for awaiting the response headers.
66 * * SeekableRequestReadStream is a higher-level tool meant for usage
67 * when knowing the length is vital, e.g. reading from a remote ZIP file.
68 */
69 $this->remote->await_response();
70 if ( null === $this->remote->length() ) {
71 // The server did not send the Content-Length header.
72 // We need to consume the entire stream to infer the length.
73 $position = $this->tell();
74 $this->consume_all();
75 $this->seek( $position );
76 }
77 $this->length_resolved = true;
78 }
79
80 return $this->remote->length();
81 }
82
83 public function tell(): int {
84 return $this->cache->tell();
85 }
86
87 public function seek( int $offset ): void {
88 $this->pipe_until( $offset );
89 $this->cache->seek( $offset );
90 }
91
92 public function reached_end_of_data(): bool {
93 return $this->remote->reached_end_of_data() && $this->cache->reached_end_of_data();
94 }
95
96 public function pull( ?int $n, string $mode = self::PULL_NO_MORE_THAN ): int {
97 $this->pipe_until( $this->tell() + $n );
98
99 return $this->cache->pull( $n, $mode );
100 }
101
102 public function peek( int $n ): string {
103 $this->pipe_until( $this->tell() + $n );
104
105 return $this->cache->peek( $n );
106 }
107
108 public function consume( int $n ): string {
109 return $this->cache->consume( $n );
110 }
111
112 public function consume_all(): string {
113 while ( ! $this->remote->reached_end_of_data() ) {
114 $pulled = $this->remote->pull( BaseByteReadStream::CHUNK_SIZE_BYTES );
115 if ( $pulled > 0 ) {
116 $this->cache->append_bytes( $this->remote->consume( $pulled ) );
117 }
118 }
119 $this->cache->close_writing();
120
121 return $this->cache->consume_all();
122 }
123
124 public function await_response() {
125 return $this->remote->await_response();
126 }
127
128 public function close_reading(): void {
129 $this->remote->close_reading();
130 $this->cache->close_reading();
131 @unlink( $this->temp );
132 }
133 }
134