php-http /
zend-adapter
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Http\Adapter\Zend; |
||
| 4 | |||
| 5 | use Http\Client\Exception\NetworkException; |
||
| 6 | use Http\Client\HttpClient; |
||
| 7 | use Http\Discovery\MessageFactoryDiscovery; |
||
| 8 | use Http\Message\ResponseFactory; |
||
| 9 | use Psr\Http\Message\RequestInterface; |
||
| 10 | use Zend\Http\Client as ZendClient; |
||
| 11 | use Zend\Http\Exception\RuntimeException; |
||
| 12 | use Zend\Http\Header\GenericHeader; |
||
| 13 | use Zend\Http\Headers; |
||
| 14 | use Zend\Http\Request; |
||
| 15 | |||
| 16 | class Client implements HttpClient |
||
| 17 | { |
||
| 18 | /** @var ZendClient */ |
||
| 19 | private $client; |
||
| 20 | |||
| 21 | /** @var ResponseFactory */ |
||
| 22 | private $responseFactory; |
||
| 23 | |||
| 24 | 82 | public function __construct(ZendClient $client = null, ResponseFactory $responseFactory = null) |
|
| 25 | { |
||
| 26 | 82 | $this->client = $client ?: new ZendClient(); |
|
| 27 | 82 | $this->responseFactory = $responseFactory ?: MessageFactoryDiscovery::find(); |
|
| 28 | 82 | } |
|
| 29 | |||
| 30 | /** |
||
| 31 | * {@inheritdoc} |
||
| 32 | */ |
||
| 33 | 82 | public function sendRequest(RequestInterface $request) |
|
| 34 | { |
||
| 35 | 82 | $request = $this->sanitizeRequest($request); |
|
| 36 | 82 | $headers = new Headers(); |
|
| 37 | |||
| 38 | 82 | foreach ($request->getHeaders() as $key => $value) { |
|
|
0 ignored issues
–
show
|
|||
| 39 | 82 | $headers->addHeader(new GenericHeader($key, $request->getHeaderLine($key))); |
|
|
0 ignored issues
–
show
The method
getHeaderLine does only exist in Psr\Http\Message\RequestInterface, but not in Http\Adapter\Zend\Client.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 40 | 82 | } |
|
| 41 | |||
| 42 | 82 | $zendRequest = new Request(); |
|
| 43 | 82 | $zendRequest->setMethod($request->getMethod()); |
|
|
0 ignored issues
–
show
The method
getMethod does only exist in Psr\Http\Message\RequestInterface, but not in Http\Adapter\Zend\Client.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 44 | 82 | $zendRequest->setUri((string) $request->getUri()); |
|
|
0 ignored issues
–
show
The method
getUri does only exist in Psr\Http\Message\RequestInterface, but not in Http\Adapter\Zend\Client.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 45 | 82 | $zendRequest->setHeaders($headers); |
|
| 46 | 82 | $zendRequest->setContent($request->getBody()->getContents()); |
|
|
0 ignored issues
–
show
The method
getBody does only exist in Psr\Http\Message\RequestInterface, but not in Http\Adapter\Zend\Client.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 47 | |||
| 48 | $options = [ |
||
| 49 | 82 | 'httpversion' => $request->getProtocolVersion(), |
|
|
0 ignored issues
–
show
|
|||
| 50 | 82 | ]; |
|
| 51 | |||
| 52 | 82 | if (extension_loaded('curl')) { |
|
| 53 | 82 | $options['curloptions'] = [ |
|
| 54 | 82 | CURLOPT_HTTP_VERSION => $this->getProtocolVersion($request->getProtocolVersion()), |
|
|
0 ignored issues
–
show
|
|||
| 55 | ]; |
||
| 56 | 82 | } |
|
| 57 | |||
| 58 | 82 | $this->client->setOptions($options); |
|
| 59 | |||
| 60 | 82 | if ($this->client->getAdapter() instanceof ZendClient\Adapter\Curl && $request->getMethod()) { |
|
| 61 | 31 | $request = $request->withHeader('Content-Length', '0'); |
|
|
0 ignored issues
–
show
The method
withHeader does only exist in Psr\Http\Message\RequestInterface, but not in Http\Adapter\Zend\Client.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 62 | 31 | } |
|
| 63 | |||
| 64 | try { |
||
| 65 | 82 | $zendResponse = $this->client->send($zendRequest); |
|
| 66 | 82 | } catch (RuntimeException $exception) { |
|
| 67 | 2 | throw new NetworkException($exception->getMessage(), $request, $exception); |
|
| 68 | } |
||
| 69 | |||
| 70 | 80 | return $this->responseFactory->createResponse( |
|
| 71 | 80 | $zendResponse->getStatusCode(), |
|
| 72 | 80 | $zendResponse->getReasonPhrase(), |
|
| 73 | 80 | $zendResponse->getHeaders()->toArray(), |
|
| 74 | 80 | $zendResponse->getContent(), |
|
| 75 | 80 | $zendResponse->getVersion() |
|
| 76 | 80 | ); |
|
| 77 | } |
||
| 78 | |||
| 79 | 82 | private function sanitizeRequest(RequestInterface $request) |
|
| 80 | { |
||
| 81 | 82 | $request = $this->sanitizeWithTrace($request); |
|
| 82 | 82 | $request = $this->sanitizeWithCurl($request); |
|
|
0 ignored issues
–
show
It seems like
$request defined by $this->sanitizeWithCurl($request) on line 82 can also be of type object<Http\Adapter\Zend\Client>; however, Http\Adapter\Zend\Client::sanitizeWithCurl() does only seem to accept object<Psr\Http\Message\RequestInterface>, maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. Loading history...
|
|||
| 83 | |||
| 84 | 82 | return $request; |
|
| 85 | } |
||
| 86 | |||
| 87 | /** |
||
| 88 | * Zend request remove the body if it's a trace but does not rewrite the content length header, |
||
| 89 | * This can lead to error from the server has it can expect a specific content length, but don't have |
||
| 90 | * a body, so we set content-length to 0 to avoid bad reading from the server. |
||
| 91 | * |
||
| 92 | * @param RequestInterface $request |
||
| 93 | * |
||
| 94 | * @return RequestInterface|static |
||
| 95 | */ |
||
| 96 | 82 | private function sanitizeWithTrace(RequestInterface $request) |
|
| 97 | { |
||
| 98 | 82 | if ('TRACE' === $request->getMethod()) { |
|
| 99 | 4 | $request = $request->withHeader('Content-Length', '0'); |
|
| 100 | 4 | } |
|
| 101 | |||
| 102 | 82 | return $request; |
|
| 103 | } |
||
| 104 | |||
| 105 | /** |
||
| 106 | * On cUrl Adapter, zend does not include the body if it's not a POST, PUT or PATCH request but does not |
||
| 107 | * rewrite the content length header. |
||
| 108 | * This can lead to error from the server has it can expect a specific content length, but don't have |
||
| 109 | * a body, so we set content-length to 0 to avoid bad reading from the server. |
||
| 110 | * |
||
| 111 | * @param RequestInterface $request |
||
| 112 | * |
||
| 113 | * @return RequestInterface|static |
||
| 114 | */ |
||
| 115 | 82 | private function sanitizeWithCurl(RequestInterface $request) |
|
| 116 | { |
||
| 117 | 82 | if ($this->client->getAdapter() instanceof ZendClient\Adapter\Curl && !in_array($request->getMethod(), [ |
|
| 118 | 31 | 'POST', |
|
| 119 | 31 | 'PUT', |
|
| 120 | 31 | 'PATCH', |
|
| 121 | 82 | ], true)) { |
|
| 122 | 23 | $request = $request->withHeader('Content-Length', '0'); |
|
| 123 | 23 | } |
|
| 124 | |||
| 125 | 82 | return $request; |
|
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * Return cURL constant for specified HTTP version. |
||
| 130 | * |
||
| 131 | * @param string $requestVersion |
||
| 132 | * |
||
| 133 | * @throws \UnexpectedValueException if unsupported version requested |
||
| 134 | * |
||
| 135 | * @return int |
||
| 136 | */ |
||
| 137 | 82 | private function getProtocolVersion($requestVersion) |
|
| 138 | { |
||
| 139 | switch ($requestVersion) { |
||
| 140 | 82 | case '1.0': |
|
| 141 | 18 | return CURL_HTTP_VERSION_1_0; |
|
| 142 | 64 | case '1.1': |
|
| 143 | 64 | return CURL_HTTP_VERSION_1_1; |
|
| 144 | case '2.0': |
||
| 145 | if (defined('CURL_HTTP_VERSION_2_0')) { |
||
| 146 | return CURL_HTTP_VERSION_2_0; |
||
| 147 | } |
||
| 148 | |||
| 149 | throw new \UnexpectedValueException('libcurl 7.33 needed for HTTP 2.0 support'); |
||
| 150 | } |
||
| 151 | |||
| 152 | return CURL_HTTP_VERSION_NONE; |
||
| 153 | } |
||
| 154 | } |
||
| 155 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: