Skip to content

Commit

Permalink
implement cookie get and set
Browse files Browse the repository at this point in the history
  • Loading branch information
gsouf committed Aug 28, 2018
1 parent 30b7322 commit 78b2e6c
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 11 deletions.
13 changes: 11 additions & 2 deletions src/Communication/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,18 @@ public function isSuccessful()
* Get the error message if set.
* @return string|null
*/
public function getErrorMessage()
public function getErrorMessage(bool $extended = true)
{
return $this->data['error']['message'] ?? null;
$message = [];
if (isset($this->data['error']['message'])) {
$message[] = $this->data['error']['message'];
}

if ($extended && isset($this->data['error']['data']) && is_string($this->data['error']['data'])) {
$message[] = $this->data['error']['data'];
}

return implode(' - ', $message);
}

/**
Expand Down
25 changes: 25 additions & 0 deletions src/Cookies/Cookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class Cookie implements \ArrayAccess
*/
public function __construct(array $data)
{
if (isset($data['expires']) && is_string($data['expires']) && !is_numeric($data['expires'])) {
$data['expires'] = strtotime($data['expires']);
}

$this->data = $data;
}

Expand All @@ -38,6 +42,14 @@ public function getName()
return $this->offsetGet('name');
}

/**
* @return mixed|null
*/
public function getDomain()
{
return $this->offsetGet('domain');
}

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -69,4 +81,17 @@ public function offsetUnset($offset)
{
throw new \RuntimeException('Cannot unset cookie values');
}

/**
* @param $name
* @param $value
* @param $params
* @return Cookie
*/
public static function create($name, $value, array $params = [])
{
$params['name'] = $name;
$params['value'] = $value;
return new Cookie($params);
}
}
52 changes: 52 additions & 0 deletions src/Cookies/CookiesCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,56 @@ public function getAt($i): Cookie
}
return $this->cookies[$i];
}

/**
* Find cookies with matching values
*
* usage:
*
* ```
* // find cookies having name == 'foo'
* $newCookies = $cookies->filterBy('name', 'foo');
*
* // find cookies having domain == 'example.com'
* $newCookies = $cookies->filterBy('domain', 'example.com');
* ```
*
* @param string $param
* @param string $value
* @return CookiesCollection
*/
public function filterBy(string $param, string $value)
{
return new CookiesCollection(array_filter($this->cookies, function (Cookie $cookie) use ($param, $value) {
return $cookie[$param] == $value;
}));
}

/**
* Find first cookies with matching value
*
* usage:
*
* ```
* // find first cookie having name == 'foo'
* $cookie = $cookies->findOneBy('name', 'foo');
*
* if ($cookie) {
* // do something
* }
* ```
*
* @param string $param
* @param string $value
* @return Cookie|null
*/
public function findOneBy(string $param, string $value)
{
foreach ($this->cookies as $cookie) {
if ($cookie[$param] == $value) {
return $cookie;
}
}
return null;
}
}
113 changes: 112 additions & 1 deletion src/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use HeadlessChromium\Communication\Message;
use HeadlessChromium\Communication\Session;
use HeadlessChromium\Communication\Target;
use HeadlessChromium\Cookies\Cookie;
use HeadlessChromium\Cookies\CookiesCollection;
use HeadlessChromium\Exception\CommunicationException;
use HeadlessChromium\Exception\NoResponseAvailable;
use HeadlessChromium\Exception\TargetDestroyed;
Expand Down Expand Up @@ -400,21 +402,29 @@ public function getCurrentUrl()
}

/**
* Read cookies
* Read cookies for the current page
*
* usage:
*
* ```
* $page->readCookies()->await()->getCookies();
* ```
*
* @see getCookies
* @see readAllCookies
* @see getAllCookies
*
* @return CookiesGetter
* @throws CommunicationException
* @throws CommunicationException\CannotReadResponse
* @throws CommunicationException\InvalidResponse
*/
public function readCookies()
{
// ensure target is not closed
$this->assertNotClosed();

// read cookies async
$response = $this->getSession()->sendMessage(
new Message(
'Network.getCookies',
Expand All @@ -424,6 +434,107 @@ public function readCookies()
)
);

// return async helper
return new CookiesGetter($response);
}

/**
* Read all cookies in the browser
*
* @see getCookies
* @see readCookies
* @see getAllCookies
*
* ```
* $page->readCookies()->await()->getCookies();
* ```
* @return CookiesGetter
* @throws CommunicationException
*/
public function readAllCookies()
{
// ensure target is not closed
$this->assertNotClosed();

// read cookies async
$response = $this->getSession()->sendMessage(new Message('Network.getAllCookies'));

// return async helper
return new CookiesGetter($response);
}

/**
* Get cookies for the current page synchronously
*
* @see readCookies
* @see readAllCookies
* @see getAllCookies
*
* @param int|null $timeout
* @return CookiesCollection
* @throws CommunicationException
* @throws Exception\OperationTimedOut
* @throws NoResponseAvailable
*/
public function getCookies(int $timeout = null)
{
return $this->readCookies()->await($timeout)->getCookies();
}

/**
* Get all browser cookies synchronously
*
* @see getCookies
* @see readAllCookies
* @see readCookies
*
* @param int|null $timeout
* @return CookiesCollection
* @throws CommunicationException
* @throws Exception\OperationTimedOut
* @throws NoResponseAvailable
*/
public function getAllCookies(int $timeout = null)
{
return $this->readAllCookies()->await($timeout)->getCookies();
}

/**
* @param Cookie[]|CookiesCollection $cookies
*/
public function setCookies($cookies)
{
// define params to send in cookie message
$allowedParams = ['url', 'domain', 'path', 'secure', 'httpOnly', 'sameSite', 'expires'];

// init list of cookies to send
$browserCookies = [];

// feed list of cookies to send
foreach ($cookies as $cookie) {
$browserCookie = [
'name' => $cookie->getName(),
'value' => $cookie->getValue(),
];

foreach ($allowedParams as $param) {
if ($cookie->offsetExists($param)) {
$browserCookie[$param] = $cookie->offsetGet($param);
}
}

// set domain from current page
if (!isset($browserCookie['domain'])) {
$browserCookie['domain'] = parse_url($this->getCurrentUrl(), PHP_URL_HOST);
}

$browserCookies[] = $browserCookie;
}

// send cookies
$response = $this->getSession()->sendMessage(new Message('Network.setCookies', ['cookies' => $browserCookies]));

// return async helper
return new ResponseWaiter($response);
}
}
8 changes: 8 additions & 0 deletions src/PageUtils/ResponseWaiter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace HeadlessChromium\PageUtils;

use HeadlessChromium\Communication\ResponseReader;
use HeadlessChromium\Exception\CommunicationException\ResponseHasError;

class ResponseWaiter
{
Expand All @@ -27,13 +28,20 @@ public function __construct(ResponseReader $responseReader)
* @param $time
* @throws \HeadlessChromium\Exception\NoResponseAvailable
* @throws \HeadlessChromium\Exception\OperationTimedOut
* @throws \HeadlessChromium\Exception\CommunicationException\ResponseHasError
*
* @return $this
*/
public function await(int $time = null)
{
$this->responseReader->waitForResponse($time);

$response = $this->responseReader->getResponse();

if (!$response->isSuccessful()) {
throw new ResponseHasError($response->getErrorMessage(true));
}

return $this;
}

Expand Down
Loading

0 comments on commit 78b2e6c

Please sign in to comment.