Skip to content

Commit

Permalink
Rewrite HTTP client handling
Browse files Browse the repository at this point in the history
  • Loading branch information
andig committed Jan 28, 2019
1 parent 9ec65a2 commit 38e6fe4
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 207 deletions.
8 changes: 7 additions & 1 deletion config.example.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
'url' => 'https://...',
'user' => '',
'password' => '',
// 'authentication' => 'digest' // uncomment for digest auth
'http' => [ // http client options are directly passed to Guzzle http client
// 'verify' => false, // uncomment to disable certificate check
// 'auth' => 'digest', // uncomment for digest auth
]
],
/* add as many as you need
[
Expand All @@ -31,6 +34,9 @@
'user' => '',
'password' => '',
'fonpix' => '/[YOURUSBSTICK]/FRITZ/fonpix', // the storage on your usb stick for uploading images
'http' => [ // http client options are directly passed to Guzzle http client
// 'verify' => false, // uncomment to disable certificate check
]
],

'filters' => [
Expand Down
175 changes: 31 additions & 144 deletions src/CardDav/Backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

namespace Andig\CardDav;

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Ringcentral\Psr7;
use Andig\Http\ClientTrait;
use Andig\Vcard\Parser;

/**
Expand All @@ -15,6 +13,8 @@

class Backend
{
use ClientTrait;

/**
* CardDAV server url
*
Expand All @@ -29,39 +29,11 @@ class Backend
*/
private $url_vcard_extension = '.vcf';

/**
* Authentication: username
*
* @var string
*/
private $username;

/**
* Authentication: password
*
* @var string
*/
private $password;

/**
* Authentication: method
*
* @var string|null
*/
private $authentication;

/**
* Progress callback
*/
private $callback;

/**
* Do not use this directly! Rather use {@see getClient()}
*
* @var Client
*/
private $client;

/**
* Set substitutions of links to embedded data
*/
Expand Down Expand Up @@ -120,15 +92,6 @@ public function setProgress($callback = null)
$this->callback = $callback;
}

/**
* Set credentials
*/
public function setAuth(string $username, string $password, string $method = null)
{
$this->username = $username;
$this->password = $password;
$this->authentication = $method;
}

/**
* Gets all vCards including additional information from the CardDAV server
Expand All @@ -137,43 +100,9 @@ public function setAuth(string $username, string $password, string $method = nul
*/
public function getVcards()
{
$response = $this->query($this->url, 'PROPFIND');

if (in_array($response->getStatusCode(), [200,207])) {
$body = (string)$response->getBody();
return $this->processPropFindResponse($body);
}

throw new \Exception('Received HTTP ' . $response->getStatusCode());
}

/**
* Get initialized HTTP client
*
* @return Client
*/
private function getClient(): Client
{
if (!$this->client) {
$this->client = new Client($this->getClientOptions());
}

return $this->client;
}

/**
* HTTP client options
*
* @param array $options
* @return array
*/
private function getClientOptions($options = []): array
{
if ($this->username) {
$options['auth'] = [$this->username, $this->password, $this->authentication];
}

return $options;
$response = $this->getClient()->request('PROPFIND', $this->url);
$body = (string)$response->getBody();
return $this->processPropFindResponse($body);
}

/**
Expand Down Expand Up @@ -230,31 +159,20 @@ private function embedBase64($vcard, $substituteID, $server)
*/
public function getLinkedData($uri)
{
$request = new Request('GET', $uri);

if ($this->username) {
$credentials = base64_encode($this->username . ':' . $this->password);
$request = $request->withHeader('Authorization', 'Basic ' . $credentials);
}
$response = $this->getClient()->send($request);

if (200 !== $response->getStatusCode()) {
throw new \Exception('Received HTTP ' . $response->getStatusCode());
} else {
$contentType = $response->getHeader('Content-Type');

@list($mimeType, $parameters) = explode(';', $contentType[0], 2);
@list($type, $subType) = explode('/', $mimeType);

$externalData = [
'mimetype' => $mimeType ?? '',
'type' => $type ?? '',
'subtype' => $subType ?? '',
'parameters' => $parameters ?? '',
'data' => (string)$response->getBody(),
];
return $externalData;
}
$response = $this->getClient()->request('GET', $uri);
$contentType = $response->getHeader('Content-Type');

@list($mimeType, $parameters) = explode(';', $contentType[0], 2);
@list($type, $subType) = explode('/', $mimeType);

$externalData = [
'mimetype' => $mimeType ?? '',
'type' => $type ?? '',
'subtype' => $subType ?? '',
'parameters' => $parameters ?? '',
'data' => (string)$response->getBody(),
];
return $externalData;
}

/**
Expand All @@ -266,27 +184,23 @@ public function getLinkedData($uri)
public function getVcard($vcard_id)
{
$vcard_id = str_replace($this->url_vcard_extension, null, $vcard_id);
$response = $this->query($this->url . $vcard_id . $this->url_vcard_extension, 'GET');
$response = $this->getClient()->request('GET', $this->url . $vcard_id . $this->url_vcard_extension);

if (in_array($response->getStatusCode(), [200,207])) {
$body = (string)$response->getBody();
$body = (string)$response->getBody();

$parser = new Parser($body);
$vcard = $parser->getCardAtIndex(0);
$parser = new Parser($body);
$vcard = $parser->getCardAtIndex(0);

if (isset($this->substitutes)) {
foreach ($this->substitutes as $substitute) {
$vcard = $this->embedBase64($vcard, $substitute, $this->url);
}
}
if (is_callable($this->callback)) {
($this->callback)();
if (isset($this->substitutes)) {
foreach ($this->substitutes as $substitute) {
$vcard = $this->embedBase64($vcard, $substitute, $this->url);
}

return $vcard;
}
if (is_callable($this->callback)) {
($this->callback)();
}

throw new \Exception('Received HTTP ' . $response->getStatusCode());
return $vcard;
}

/**
Expand Down Expand Up @@ -331,31 +245,4 @@ private function cleanResponse($response)

return $response;
}

/**
* Query the CardDAV server via curl and returns the response
*
* @param string $url CardDAV server URL
* @param string $method HTTP method like (OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE)
* @param string $content Content for CardDAV queries
* @param string $content_type Set content type
* @return array Raw CardDAV Response and http status code
*/
private function query($url, $method, $content = null, $content_type = null)
{
$request = new Request($method, $url, [
'Depth' => '1'
]);

if ($content_type) {
$request = $request->withHeader('Content-type', $content_type);
}

if ($content) {
$request = $request->withBody($content);
}

$response = $this->getClient()->send($request);
return $response;
}
}
74 changes: 19 additions & 55 deletions src/FritzBox/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,38 @@

namespace Andig\FritzBox;

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Ringcentral\Psr7;
use Andig\Http\ClientTrait;

define('EMPTY_SID', '0000000000000000');

/**
* Copyright (c) 2019 Andreas Götz
* @license MIT
*/
class Api
{
private $username;
private $password;
private $url;
use ClientTrait;

protected $sid = '0000000000000000';
/** @var string */
protected $username;

/**
* Do not use this directly! Rather use {@see getClient()}
*
* @var Client
*/
private $client;
/** @var string */
protected $password;

/** @var string */
protected $url;

/** @var string */
protected $sid = EMPTY_SID;

/**
* Execute fb login
*
* @access public
*/
public function __construct($url = 'https://fritz.box', $username = false, $password = false)
public function __construct($url = 'https://fritz.box')
{
$this->url = rtrim($url, '/');
$this->username = $username;
$this->password = $password;

$this->initSID();
}

/**
Expand All @@ -49,31 +46,6 @@ public function getSID()
return $this->sid;
}

/**
* Get initialized HTTP client
*
* @return Client
*/
private function getClient(): Client
{
if (!$this->client) {
$this->client = new Client($this->getClientOptions());
}

return $this->client;
}

/**
* HTTP client options
*
* @param array $options
* @return array
*/
private function getClientOptions($options = []): array
{
return $options;
}

/**
* Multi-part file uploads
*
Expand Down Expand Up @@ -124,19 +96,14 @@ public function postFile(array $formFields, array $fileFields)
*
* @throws Exception
*/
protected function initSID()
protected function login()
{
$url = $this->url . '/login_sid.lua';

// read the current status
$resp = $this->getClient()->request('GET', $url);
if (200 !== $resp->getStatusCode()) {
throw new \Exception('Received HTTP ' . $resp->getStatusCode());
}

// process response
$xml = simplexml_load_string((string)$resp->getBody());
if ($xml->SID != '0000000000000000') {
if ($xml->SID != EMPTY_SID) {
$this->sid = (string)$xml->SID;
return;
}
Expand All @@ -151,13 +118,10 @@ protected function initSID()
'response' => $response,
]
]);
if (200 !== $resp->getStatusCode()) {
throw new \Exception('Received HTTP ' . $resp->getStatusCode());
}

// finger out the SID from the response
// retrieve SID from response
$xml = simplexml_load_string((string)$resp->getBody());
if ($xml->SID != '0000000000000000') {
if ($xml->SID != EMPTY_SID) {
$this->sid = (string)$xml->SID;
return;
}
Expand Down
Loading

0 comments on commit 38e6fe4

Please sign in to comment.