Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

File tree

12 files changed

+355
-22
lines changed

12 files changed

+355
-22
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zendframework/zend-http",
3-
"description": "provides an easy interface for preforming Hyper-Text Transfer Protocol (HTTP) requests",
3+
"description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests",
44
"license": "BSD-3-Clause",
55
"keywords": [
66
"zf2",

src/Client.php

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,10 @@ public function setStream($streamfile = true)
582582
*/
583583
public function getStream()
584584
{
585+
if (!is_null($this->streamName)) {
586+
return $this->streamName;
587+
}
588+
585589
return $this->config['outputstream'];
586590
}
587591

@@ -631,8 +635,8 @@ public function setAuth($user, $password, $type = self::AUTH_BASIC)
631635
if (!defined('self::AUTH_' . strtoupper($type))) {
632636
throw new Exception\InvalidArgumentException("Invalid or not supported authentication type: '$type'");
633637
}
634-
if (empty($user) || empty($password)) {
635-
throw new Exception\InvalidArgumentException("The username and the password cannot be empty");
638+
if (empty($user)) {
639+
throw new Exception\InvalidArgumentException("The username cannot be empty");
636640
}
637641

638642
$this->auth = array (
@@ -834,10 +838,6 @@ public function send(Request $request = null)
834838
if (!is_resource($stream) && is_string($stream)) {
835839
$stream = fopen($stream, 'r');
836840
}
837-
if (!is_resource($stream)) {
838-
$stream = $this->getUri()->toString();
839-
$stream = fopen($stream, 'r');
840-
}
841841
$streamMetaData = stream_get_meta_data($stream);
842842
if ($streamMetaData['seekable']) {
843843
rewind($stream);
@@ -1040,11 +1040,11 @@ protected function prepareHeaders($body, $uri)
10401040

10411041
// Set the Accept-encoding header if not set - depending on whether
10421042
// zlib is available or not.
1043-
if (! isset($this->headers['accept-encoding'])) {
1043+
if (!$this->getRequest()->getHeaders()->has('Accept-Encoding')) {
10441044
if (function_exists('gzinflate')) {
1045-
$headers['Accept-encoding'] = 'gzip, deflate';
1045+
$headers['Accept-Encoding'] = 'gzip, deflate';
10461046
} else {
1047-
$headers['Accept-encoding'] = 'identity';
1047+
$headers['Accept-Encoding'] = 'identity';
10481048
}
10491049
}
10501050

@@ -1301,4 +1301,42 @@ protected function doRequest(Http $uri, $method, $secure = false, $headers = arr
13011301

13021302
return $this->adapter->read();
13031303
}
1304+
1305+
/**
1306+
* Create a HTTP authentication "Authorization:" header according to the
1307+
* specified user, password and authentication method.
1308+
*
1309+
* @see http://www.faqs.org/rfcs/rfc2617.html
1310+
* @param string $user
1311+
* @param string $password
1312+
* @param string $type
1313+
* @return string
1314+
* @throws Zend\Http\Client\Exception\InvalidArgumentException
1315+
*/
1316+
public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC)
1317+
{
1318+
$authHeader = null;
1319+
1320+
switch ($type) {
1321+
case self::AUTH_BASIC:
1322+
// In basic authentication, the user name cannot contain ":"
1323+
if (strpos($user, ':') !== false) {
1324+
throw new Client\Exception\InvalidArgumentException("The user name cannot contain ':' in 'Basic' HTTP authentication");
1325+
}
1326+
1327+
$authHeader = 'Basic ' . base64_encode($user . ':' . $password);
1328+
break;
1329+
1330+
//case self::AUTH_DIGEST:
1331+
/**
1332+
* @todo Implement digest authentication
1333+
*/
1334+
// break;
1335+
1336+
default:
1337+
throw new Client\Exception\InvalidArgumentException("Not a supported HTTP authentication type: '$type'");
1338+
1339+
}
1340+
return $authHeader;
1341+
}
13041342
}

src/Client/Adapter/Curl.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $bo
283283
foreach ($headers AS $k => $header) {
284284
if (preg_match('/Content-Length:\s*(\d+)/i', $header, $m)) {
285285
if (is_resource($body)) {
286-
$this->config['curloptions'][CURLOPT_INFILESIZE] = (int)$m[1];
286+
$this->config['curloptions'][CURLOPT_INFILESIZE] = (int) $m[1];
287287
}
288288
unset($headers[$k]);
289289
}

src/Client/Adapter/Socket.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ public function getStreamContext()
189189
public function connect($host, $port = 80, $secure = false)
190190
{
191191
// If we are connected to the wrong host, disconnect first
192-
if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
192+
$connected_host = (strpos($this->connected_to[0], '://'))
193+
? substr($this->connected_to[0], (strpos($this->connected_to[0], '://') + 3), strlen($this->connected_to[0]))
194+
: $this->connected_to[0];
195+
196+
if ($connected_host != $host || $this->connected_to[1] != $port) {
193197
if (is_resource($this->socket)) {
194198
$this->close();
195199
}
@@ -360,7 +364,7 @@ public function write($method, $uri, $http_ver = '1.1', $headers = array(), $bod
360364
ErrorHandler::start();
361365
$test = fwrite($this->socket, $request);
362366
$error = ErrorHandler::stop();
363-
if (!$test) {
367+
if (false === $test) {
364368
throw new AdapterException\RuntimeException('Error writing request to server', 0, $error);
365369
}
366370

@@ -431,7 +435,7 @@ public function read()
431435
$line = fgets($this->socket);
432436
$this->_checkSocketReadTimeout();
433437

434-
$chunk = $line;
438+
$chunk = '';
435439

436440
// Figure out the next chunk size
437441
$chunksize = trim($line);

src/Header/AbstractAccept.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,11 @@ protected function assembleAcceptParam(&$value, $key)
220220
'/', '[', ']', '?', '=', '{', '}', ' ', "\t");
221221

222222
$escaped = preg_replace_callback('/[[:cntrl:]"\\\\]/', // escape cntrl, ", \
223-
function($v) { return '\\' . $v[0]; },
224-
$value
225-
);
223+
function ($v) {
224+
return '\\' . $v[0];
225+
},
226+
$value
227+
);
226228

227229
if ($escaped == $value && !array_intersect(str_split($value), $separators)) {
228230
$value = $key . '=' . $value;
@@ -405,7 +407,7 @@ protected function addFieldValuePartToQueue($value)
405407
*/
406408
protected function sortFieldValueParts()
407409
{
408-
$sort = function($a, $b) { // If A has higher prio than B, return -1.
410+
$sort = function ($a, $b) { // If A has higher prio than B, return -1.
409411
if ($a->priority > $b->priority) {
410412
return -1;
411413
} elseif ($a->priority < $b->priority) {

src/Header/Connection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static function fromString($headerLine)
6060
*/
6161
public function setPersistent($flag)
6262
{
63-
if ((bool)$flag === true) {
63+
if ((bool) $flag === true) {
6464
$this->value = self::CONNECTION_KEEP_ALIVE;
6565
} else {
6666
$this->value = self::CONNECTION_CLOSE;

src/Header/SetCookie.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public static function fromString($headerLine, $bypassHeaderFieldName = false)
9595

9696
if ($setCookieProcessor === null) {
9797
$setCookieClass = get_called_class();
98-
$setCookieProcessor = function($headerLine) use ($setCookieClass) {
98+
$setCookieProcessor = function ($headerLine) use ($setCookieClass) {
9999
$header = new $setCookieClass;
100100
$keyValuePairs = preg_split('#;\s*#', $headerLine);
101101
foreach ($keyValuePairs as $keyValue) {
@@ -133,6 +133,9 @@ public static function fromString($headerLine, $bypassHeaderFieldName = false)
133133

134134
list($name, $value) = explode(': ', $headerLine, 2);
135135

136+
// some sites return set-cookie::value, this is to get rid of the second :
137+
$name = (strtolower($name) =='set-cookie:') ? 'set-cookie' : $name;
138+
136139
// check to ensure proper header type for this factory
137140
if (strtolower($name) !== 'set-cookie') {
138141
throw new Exception\InvalidArgumentException('Invalid header line for Set-Cookie string: "' . $name . '"');
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
* @package Zend_Http
9+
*/
10+
11+
namespace Zend\Http\PhpEnvironment;
12+
13+
/**
14+
* Functionality for determining client IP address.
15+
*
16+
* @category Zend
17+
* @package Zend_Http
18+
*/
19+
class RemoteAddress
20+
{
21+
/**
22+
* Whether to use proxy addresses or not.
23+
*
24+
* As default this setting is disabled - IP address is mostly needed to increase
25+
* security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
26+
* just for more flexibility, but if user uses proxy to connect to trusted services
27+
* it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
28+
*
29+
* @var bool
30+
*/
31+
protected $useProxy = false;
32+
33+
/**
34+
* List of trusted proxy IP addresses
35+
*
36+
* @var array
37+
*/
38+
protected $trustedProxies = array();
39+
40+
/**
41+
* HTTP header to introspect for proxies
42+
*
43+
* @var string
44+
*/
45+
protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';
46+
47+
48+
/**
49+
* Changes proxy handling setting.
50+
*
51+
* This must be static method, since validators are recovered automatically
52+
* at session read, so this is the only way to switch setting.
53+
*
54+
* @param bool $useProxy Whether to check also proxied IP addresses.
55+
* @return RemoteAddress
56+
*/
57+
public function setUseProxy($useProxy = true)
58+
{
59+
$this->useProxy = $useProxy;
60+
return $this;
61+
}
62+
63+
/**
64+
* Checks proxy handling setting.
65+
*
66+
* @return bool Current setting value.
67+
*/
68+
public function getUseProxy()
69+
{
70+
return $this->useProxy;
71+
}
72+
73+
/**
74+
* Set list of trusted proxy addresses
75+
*
76+
* @param array $trustedProxies
77+
* @return RemoteAddress
78+
*/
79+
public function setTrustedProxies(array $trustedProxies)
80+
{
81+
$this->trustedProxies = $trustedProxies;
82+
return $this;
83+
}
84+
85+
/**
86+
* Set the header to introspect for proxy IPs
87+
*
88+
* @param string $header
89+
* @return RemoteAddress
90+
*/
91+
public function setProxyHeader($header = 'X-Forwarded-For')
92+
{
93+
$this->proxyHeader = $this->normalizeProxyHeader($header);
94+
return $this;
95+
}
96+
97+
/**
98+
* Returns client IP address.
99+
*
100+
* @return string IP address.
101+
*/
102+
public function getIpAddress()
103+
{
104+
$ip = $this->getIpAddressFromProxy();
105+
if ($ip) {
106+
return $ip;
107+
}
108+
109+
// direct IP address
110+
if (isset($_SERVER['REMOTE_ADDR'])) {
111+
return $_SERVER['REMOTE_ADDR'];
112+
}
113+
114+
return '';
115+
}
116+
117+
/**
118+
* Attempt to get the IP address for a proxied client
119+
*
120+
* @return false|string
121+
*/
122+
protected function getIpAddressFromProxy()
123+
{
124+
if (!$this->useProxy) {
125+
return false;
126+
}
127+
128+
$header = $this->proxyHeader;
129+
130+
if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {
131+
return false;
132+
}
133+
134+
// Extract IPs
135+
$ips = explode(',', $_SERVER[$header]);
136+
// trim, so we can compare against trusted proxies properly
137+
$ips = array_map('trim', $ips);
138+
// remove trusted proxy IPs
139+
$ips = array_diff($ips, $this->trustedProxies);
140+
141+
// Any left?
142+
if (empty($ips)) {
143+
return false;
144+
}
145+
146+
// Return right-most
147+
$ip = array_pop($ips);
148+
return $ip;
149+
}
150+
151+
152+
/**
153+
* Normalize a header string
154+
*
155+
* Normalizes a header string to a format that is compatible with
156+
* $_SERVER
157+
*
158+
* @param string $header
159+
* @return string
160+
*/
161+
protected function normalizeProxyHeader($header)
162+
{
163+
$header = strtoupper($header);
164+
$header = str_replace('-', '_', $header);
165+
if (0 !== strpos($header, 'HTTP_')) {
166+
$header = 'HTTP_' . $header;
167+
}
168+
return $header;
169+
}
170+
}

src/Response.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace Zend\Http;
1212

13+
use Zend\Stdlib\ErrorHandler;
1314
use Zend\Stdlib\ResponseInterface;
1415

1516
/**
@@ -476,7 +477,17 @@ protected function decodeGzip($body)
476477
);
477478
}
478479

479-
return gzinflate(substr($body, 10));
480+
ErrorHandler::start();
481+
$return = gzinflate(substr($body, 10));
482+
$test = ErrorHandler::stop();
483+
if ($test) {
484+
throw new Exception\RuntimeException(
485+
'Error occurred during gzip inflation',
486+
0,
487+
$test
488+
);
489+
}
490+
return $return;
480491
}
481492

482493
/**

0 commit comments

Comments
 (0)