diff --git a/src/Utilities/Miscellaneous.php b/src/Utilities/Miscellaneous.php
index 9014bcd..2146a29 100644
--- a/src/Utilities/Miscellaneous.php
+++ b/src/Utilities/Miscellaneous.php
@@ -1229,104 +1229,112 @@ class Miscellaneous
* to "true". To read exact length of HTTP headers from CURL you can use "curl_getinfo()" function
* and read "CURLINFO_HEADER_SIZE" option.
*
- * @param string $response the full content of response, including HTTP headers
- * @param int $headerSize The length of HTTP headers in content
+ * @param string $response Full content of response, including HTTP headers
+ * @param int $headerSize Length of HTTP headers in content
* @return array
*/
public static function getCurlResponseWithHeaders($response, $headerSize)
{
- $headerContent = mb_substr($response, 0, $headerSize);
- $content = mb_substr($response, $headerSize);
$headers = [];
$cookies = [];
+ $headerContent = '';
+ $content = '';
+
+ if (0 < $headerSize) {
+ $headerContent = mb_substr($response, 0, $headerSize);
+ $content = mb_substr($response, $headerSize);
+ }
+
/*
* Let's transform headers content into two arrays: headers and cookies
*/
- foreach (explode("\r\n", $headerContent) as $i => $line) {
- /*
- * First line is only HTTP status and is unneeded so skip it
- */
- if (0 === $i) {
- continue;
- }
-
- if (Regex::contains($line, ':')) {
- list($key, $value) = explode(': ', $line);
-
+ if (!empty($headerContent)) {
+ foreach (explode("\r\n", $headerContent) as $i => $line) {
/*
- * If the header is a "set-cookie" let's save it to "cookies" array
+ * First line is only HTTP status and is unneeded so skip it
*/
- if ('Set-Cookie' === $key) {
- $cookieParameters = explode(';', $value);
-
- $name = '';
- $value = '';
- $expire = 0;
- $path = '/';
- $domain = null;
- $secure = false;
- $httpOnly = true;
-
- foreach ($cookieParameters as $j => $parameter) {
- $param = explode('=', $parameter);
-
- /*
- * First parameter will be always a cookie name and it's value. It is not needed to run
- * further actions for them, so save the values and move to next parameter.
- */
- if (0 === $j) {
- $name = trim($param[0]);
- $value = trim($param[1]);
- continue;
- }
-
- /*
- * Now there would be the rest of cookie parameters, names of params are sent different way so
- * I need to lowercase the names and remove unneeded spaces.
- */
- $paramName = mb_strtolower(trim($param[0]));
- $paramValue = true;
-
- /*
- * Some parameters don't have value e.g. "secure", but the value for them if they're specified
- * is "true". Otherwise - just read a value for parameter if exists.
- */
- if (array_key_exists(1, $param)) {
- $paramValue = trim($param[1]);
- }
-
- switch ($paramName) {
- case 'expires':
- $expire = $paramValue;
- break;
- case 'path':
- $path = $paramValue;
- break;
- case 'domain':
- $domain = $paramValue;
- break;
- case 'secure':
- $secure = $paramValue;
- break;
- case 'httponly':
- $httpOnly = $paramValue;
- break;
- }
- }
-
- /*
- * Create new Cookie object and add it to "cookies" array.
- * I must skip to next header as cookies shouldn't be saved in "headers" array.
- */
- $cookies[] = new Cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
+ if (0 === $i) {
continue;
}
- /*
- * Save response header which is not a cookie
- */
- $headers[$key] = $value;
+ if (Regex::contains($line, ':')) {
+ list($key, $value) = explode(': ', $line);
+
+ /*
+ * If the header is a "set-cookie" let's save it to "cookies" array
+ */
+ if ('Set-Cookie' === $key) {
+ $cookieParameters = explode(';', $value);
+
+ $name = '';
+ $value = '';
+ $expire = 0;
+ $path = '/';
+ $domain = null;
+ $secure = false;
+ $httpOnly = true;
+
+ foreach ($cookieParameters as $j => $parameter) {
+ $param = explode('=', $parameter);
+
+ /*
+ * First parameter will be always a cookie name and it's value. It is not needed to run
+ * further actions for them, so save the values and move to next parameter.
+ */
+ if (0 === $j) {
+ $name = trim($param[0]);
+ $value = trim($param[1]);
+ continue;
+ }
+
+ /*
+ * Now there would be the rest of cookie parameters, names of params are sent different way so
+ * I need to lowercase the names and remove unneeded spaces.
+ */
+ $paramName = mb_strtolower(trim($param[0]));
+ $paramValue = true;
+
+ /*
+ * Some parameters don't have value e.g. "secure", but the value for them if they're specified
+ * is "true". Otherwise - just read a value for parameter if exists.
+ */
+ if (array_key_exists(1, $param)) {
+ $paramValue = trim($param[1]);
+ }
+
+ switch ($paramName) {
+ case 'expires':
+ $expire = $paramValue;
+ break;
+ case 'path':
+ $path = $paramValue;
+ break;
+ case 'domain':
+ $domain = $paramValue;
+ break;
+ case 'secure':
+ $secure = $paramValue;
+ break;
+ case 'httponly':
+ $httpOnly = $paramValue;
+ break;
+ }
+ }
+
+ /*
+ * Create new Cookie object and add it to "cookies" array.
+ * I must skip to next header as cookies shouldn't be saved in "headers" array.
+ */
+ $cookies[] = new Cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
+ continue;
+ }
+
+ /*
+ * Save response header which is not a cookie
+ */
+ $headers[$key] = $value;
+ }
}
}
diff --git a/tests/Utilities/MiscellaneousTest.php b/tests/Utilities/MiscellaneousTest.php
index 967a879..db3145d 100644
--- a/tests/Utilities/MiscellaneousTest.php
+++ b/tests/Utilities/MiscellaneousTest.php
@@ -28,6 +28,7 @@ class MiscellaneousTest extends BaseTestCase
private $stringSmall;
private $stringCommaSeparated;
private $stringDotSeparated;
+ private $stringWithoutSpaces;
/**
* @throws ReflectionException
@@ -365,6 +366,7 @@ class MiscellaneousTest extends BaseTestCase
{
self::assertEquals('Lorem ipsum dolor sit
amet, consectetur
adipiscing
elit', Miscellaneous::breakLongText($this->stringCommaSeparated, 20));
self::assertEquals('Lorem ipsum dolor sit---amet, consectetur---adipiscing---elit', Miscellaneous::breakLongText($this->stringCommaSeparated, 20, '---'));
+ self::assertEquals('LoremIpsum
DolorSitAm
etConsecte
turAdipisc
ingElit', Miscellaneous::breakLongText($this->stringWithoutSpaces, 10));
}
public function testRemoveDirectoryUsingNotExistingDirectory()
@@ -768,6 +770,21 @@ class MiscellaneousTest extends BaseTestCase
self::assertNotEmpty(Miscellaneous::getProjectRootPath());
}
+ /**
+ * @param int $headerSize Length of HTTP headers in content
+ * @dataProvider provideHeaderSizeForEmptyCurlResponse
+ */
+ public function testGetCurlResponseWithHeadersUsingEmptyResponse($headerSize)
+ {
+ $expected = [
+ 'headers' => [],
+ 'cookies' => [],
+ 'content' => '',
+ ];
+
+ self::assertEquals($expected, Miscellaneous::getCurlResponseWithHeaders('', $headerSize));
+ }
+
/**
* Provides string to convert characters to latin characters and not lower cased and not human-readable
*
@@ -1178,6 +1195,30 @@ class MiscellaneousTest extends BaseTestCase
];
}
+ /**
+ * Provides length/size of HTTP headers for an empty response
+ *
+ * @return Generator
+ */
+ public function provideHeaderSizeForEmptyCurlResponse()
+ {
+ yield[
+ -10,
+ ];
+
+ yield[
+ -1,
+ ];
+
+ yield[
+ 0,
+ ];
+
+ yield[
+ 10,
+ ];
+ }
+
/**
* {@inheritdoc}
*/
@@ -1188,6 +1229,7 @@ class MiscellaneousTest extends BaseTestCase
$this->stringSmall = 'Lorem ipsum dolor sit amet.';
$this->stringCommaSeparated = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
$this->stringDotSeparated = 'Etiam ullamcorper. Suspendisse a pellentesque dui, non felis.';
+ $this->stringWithoutSpaces = 'LoremIpsumDolorSitAmetConsecteturAdipiscingElit';
}
/**
@@ -1200,5 +1242,6 @@ class MiscellaneousTest extends BaseTestCase
unset($this->stringSmall);
unset($this->stringCommaSeparated);
unset($this->stringDotSeparated);
+ unset($this->stringWithoutSpaces);
}
}