WP_Http_Encoding::content_encoding()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * HTTP API: WP_Http_Encoding class
4
 *
5
 * @package WordPress
6
 * @subpackage HTTP
7
 * @since 4.4.0
8
 */
9
10
/**
11
 * Core class used to implement deflate and gzip transfer encoding support for HTTP requests.
12
 *
13
 * Includes RFC 1950, RFC 1951, and RFC 1952.
14
 *
15
 * @since 2.8.0
16
 */
17
class WP_Http_Encoding {
18
19
	/**
20
	 * Compress raw string using the deflate format.
21
	 *
22
	 * Supports the RFC 1951 standard.
23
	 *
24
	 * @since 2.8.0
25
	 *
26
	 * @static
27
	 *
28
	 * @param string $raw String to compress.
29
	 * @param int $level Optional, default is 9. Compression level, 9 is highest.
30
	 * @param string $supports Optional, not used. When implemented it will choose the right compression based on what the server supports.
31
	 * @return string|false False on failure.
32
	 */
33
	public static function compress( $raw, $level = 9, $supports = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $supports is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
34
		return gzdeflate( $raw, $level );
35
	}
36
37
	/**
38
	 * Decompression of deflated string.
39
	 *
40
	 * Will attempt to decompress using the RFC 1950 standard, and if that fails
41
	 * then the RFC 1951 standard deflate will be attempted. Finally, the RFC
42
	 * 1952 standard gzip decode will be attempted. If all fail, then the
43
	 * original compressed string will be returned.
44
	 *
45
	 * @since 2.8.0
46
	 *
47
	 * @static
48
	 *
49
	 * @param string $compressed String to decompress.
50
	 * @param int $length The optional length of the compressed data.
51
	 * @return string|bool False on failure.
52
	 */
53
	public static function decompress( $compressed, $length = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $length is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
54
55
		if ( empty($compressed) )
56
			return $compressed;
57
58
		if ( false !== ( $decompressed = @gzinflate( $compressed ) ) )
59
			return $decompressed;
60
61
		if ( false !== ( $decompressed = self::compatible_gzinflate( $compressed ) ) )
62
			return $decompressed;
63
64
		if ( false !== ( $decompressed = @gzuncompress( $compressed ) ) )
65
			return $decompressed;
66
67
		if ( function_exists('gzdecode') ) {
68
			$decompressed = @gzdecode( $compressed );
69
70
			if ( false !== $decompressed )
71
				return $decompressed;
72
		}
73
74
		return $compressed;
75
	}
76
77
	/**
78
	 * Decompression of deflated string while staying compatible with the majority of servers.
79
	 *
80
	 * Certain Servers will return deflated data with headers which PHP's gzinflate()
81
	 * function cannot handle out of the box. The following function has been created from
82
	 * various snippets on the gzinflate() PHP documentation.
83
	 *
84
	 * Warning: Magic numbers within. Due to the potential different formats that the compressed
85
	 * data may be returned in, some "magic offsets" are needed to ensure proper decompression
86
	 * takes place. For a simple progmatic way to determine the magic offset in use, see:
87
	 * https://core.trac.wordpress.org/ticket/18273
88
	 *
89
	 * @since 2.8.1
90
	 * @link https://core.trac.wordpress.org/ticket/18273
91
	 * @link https://secure.php.net/manual/en/function.gzinflate.php#70875
92
	 * @link https://secure.php.net/manual/en/function.gzinflate.php#77336
93
	 *
94
	 * @static
95
	 *
96
	 * @param string $gzData String to decompress.
97
	 * @return string|bool False on failure.
98
	 */
99
	public static function compatible_gzinflate($gzData) {
100
101
		// Compressed data might contain a full header, if so strip it for gzinflate().
102 View Code Duplication
		if ( substr($gzData, 0, 3) == "\x1f\x8b\x08" ) {
103
			$i = 10;
104
			$flg = ord( substr($gzData, 3, 1) );
105
			if ( $flg > 0 ) {
106
				if ( $flg & 4 ) {
107
					list($xlen) = unpack('v', substr($gzData, $i, 2) );
108
					$i = $i + 2 + $xlen;
109
				}
110
				if ( $flg & 8 )
111
					$i = strpos($gzData, "\0", $i) + 1;
112
				if ( $flg & 16 )
113
					$i = strpos($gzData, "\0", $i) + 1;
114
				if ( $flg & 2 )
115
					$i = $i + 2;
116
			}
117
			$decompressed = @gzinflate( substr($gzData, $i, -8) );
118
			if ( false !== $decompressed )
119
				return $decompressed;
120
		}
121
122
		// Compressed data from java.util.zip.Deflater amongst others.
123
		$decompressed = @gzinflate( substr($gzData, 2) );
124
		if ( false !== $decompressed )
125
			return $decompressed;
126
127
		return false;
128
	}
129
130
	/**
131
	 * What encoding types to accept and their priority values.
132
	 *
133
	 * @since 2.8.0
134
	 *
135
	 * @static
136
	 *
137
	 * @param string $url
138
	 * @param array  $args
139
	 * @return string Types of encoding to accept.
140
	 */
141
	public static function accept_encoding( $url, $args ) {
142
		$type = array();
143
		$compression_enabled = self::is_available();
144
145
		if ( ! $args['decompress'] ) // Decompression specifically disabled.
146
			$compression_enabled = false;
147
		elseif ( $args['stream'] ) // Disable when streaming to file.
148
			$compression_enabled = false;
149
		elseif ( isset( $args['limit_response_size'] ) ) // If only partial content is being requested, we won't be able to decompress it.
150
			$compression_enabled = false;
151
152
		if ( $compression_enabled ) {
153
			if ( function_exists( 'gzinflate' ) )
154
				$type[] = 'deflate;q=1.0';
155
156
			if ( function_exists( 'gzuncompress' ) )
157
				$type[] = 'compress;q=0.5';
158
159
			if ( function_exists( 'gzdecode' ) )
160
				$type[] = 'gzip;q=0.5';
161
		}
162
163
		/**
164
		 * Filters the allowed encoding types.
165
		 *
166
		 * @since 3.6.0
167
		 *
168
		 * @param array  $type Encoding types allowed. Accepts 'gzinflate',
169
		 *                     'gzuncompress', 'gzdecode'.
170
		 * @param string $url  URL of the HTTP request.
171
		 * @param array  $args HTTP request arguments.
172
		 */
173
		$type = apply_filters( 'wp_http_accept_encoding', $type, $url, $args );
174
175
		return implode(', ', $type);
176
	}
177
178
	/**
179
	 * What encoding the content used when it was compressed to send in the headers.
180
	 *
181
	 * @since 2.8.0
182
	 *
183
	 * @static
184
	 *
185
	 * @return string Content-Encoding string to send in the header.
186
	 */
187
	public static function content_encoding() {
188
		return 'deflate';
189
	}
190
191
	/**
192
	 * Whether the content be decoded based on the headers.
193
	 *
194
	 * @since 2.8.0
195
	 *
196
	 * @static
197
	 *
198
	 * @param array|string $headers All of the available headers.
199
	 * @return bool
200
	 */
201
	public static function should_decode($headers) {
202
		if ( is_array( $headers ) ) {
203
			if ( array_key_exists('content-encoding', $headers) && ! empty( $headers['content-encoding'] ) )
204
				return true;
205
		} elseif ( is_string( $headers ) ) {
206
			return ( stripos($headers, 'content-encoding:') !== false );
207
		}
208
209
		return false;
210
	}
211
212
	/**
213
	 * Whether decompression and compression are supported by the PHP version.
214
	 *
215
	 * Each function is tested instead of checking for the zlib extension, to
216
	 * ensure that the functions all exist in the PHP version and aren't
217
	 * disabled.
218
	 *
219
	 * @since 2.8.0
220
	 *
221
	 * @static
222
	 *
223
	 * @return bool
224
	 */
225
	public static function is_available() {
226
		return ( function_exists('gzuncompress') || function_exists('gzdeflate') || function_exists('gzinflate') );
227
	}
228
}
229