Completed
Push — master ( d950da...d2fb93 )
by Narcotic
09:23 queued 10s
created

HttpLoader::setCurlOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
/**
3
 * HttpLoader
4
 */
5
6
namespace Graviton\ProxyBundle\Definition\Loader;
7
8
use Graviton\ProxyBundle\Definition\ApiDefinition;
9
use Graviton\ProxyBundle\Definition\Loader\DispersalStrategy\DispersalStrategyInterface;
10
use Doctrine\Common\Cache\CacheProvider;
11
use GuzzleHttp\Exception\RequestException;
12
use GuzzleHttp\Psr7\Request;
13
use Proxy\Adapter\AdapterInterface;
14
use Psr\Http\Message\RequestInterface;
15
use Psr\Log\LoggerInterface;
16
use Symfony\Component\Validator\Constraints\Url;
17
use Symfony\Component\Validator\Validator\ValidatorInterface;
18
19
/**
20
 * load a file over http and process the data
21
 *
22
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
23
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
24
 * @link     http://swisscom.ch
25
 */
26
class HttpLoader implements LoaderInterface
27
{
28
    /**
29
     * @var ValidatorInterface
30
     */
31
    private $validator;
32
33
    /**
34
     * @var AdapterInterface
35
     */
36
    private $client;
37
38
    /**
39
     * @var LoggerInterface
40
     */
41
    private $logger;
42
43
    /**
44
     * @var DispersalStrategyInterface
45
     */
46
    private $strategy;
47
48
    /**
49
     * doctrine cache
50
     *
51
     * @var CacheProvider
52
     */
53
    private $cache;
54
55
    /**
56
     * doctrine cache lifetime
57
     *
58
     * @var int
59
     */
60
    private $cacheLifetime;
61
62
    /**
63
     * @var array
64
     */
65
    private $options = [
66
        'storeKey' => 'httpLoader',
67
    ];
68
69
    /**
70
     * constructor
71
     *
72
     * @param ValidatorInterface $validator validator
73
     * @param AdapterInterface   $client    http client
74
     * @param LoggerInterface    $logger    Logger
75
     */
76 8
    public function __construct(ValidatorInterface $validator, AdapterInterface $client, LoggerInterface $logger)
77
    {
78 8
        $this->validator = $validator;
79 8
        $this->client = $client;
80 8
        $this->logger = $logger;
81 8
    }
82
83
    /**
84
     * @inheritDoc
85
     *
86
     * @param DispersalStrategyInterface $strategy dispersal strategy
87
     *
88
     * @return void
89
     */
90 6
    public function setDispersalStrategy(DispersalStrategyInterface $strategy)
91
    {
92 6
        $this->strategy = $strategy;
93 6
    }
94
95
    /**
96
     * @inheritDoc
97
     *
98
     * @param CacheProvider $cache          doctrine cache provider
99
     * @param string        $cacheNamespace cache namespace
100
     * @param int           $cacheLifetime  cache lifetime
101
     *
102
     * @return void
103
     */
104 2
    public function setCache(CacheProvider $cache, $cacheNamespace, $cacheLifetime)
105
    {
106 2
        $this->cache = $cache;
107 2
        $this->cache->setNamespace($cacheNamespace);
108 2
        $this->cacheLifetime = $cacheLifetime;
109 2
    }
110
111
    /**
112
     * @inheritDoc
113
     *
114
     * @param array $options cache strategy
115
     *
116
     * @return void
117
     */
118 2
    public function setOptions($options)
119
    {
120 2
        if (!empty($options['prefix'])) {
121 2
            $options['storeKey'] = $options['prefix'];
122 2
            unset($options['prefix']);
123 1
        }
124
125 2
        $this->options = array_merge($this->options, $options);
126 2
    }
127
128
    /**
129
     * check if the url is valid
130
     *
131
     * @param string $url url
132
     *
133
     * @return boolean
134
     */
135 2
    public function supports($url)
136
    {
137 2
        $error = $this->validator->validate($url, [new Url()]);
138
139 2
        return 0 === count($error);
140
    }
141
142
    /**
143
     * @inheritDoc
144
     *
145
     * @param string $input url
146
     *
147
     * @return ApiDefinition
148
     */
149 6
    public function load($input)
150
    {
151 6
        $retVal = new ApiDefinition();
152 6
        if (isset($this->strategy)) {
153 6
            if (isset($this->cache) && $this->cache->contains($this->options['storeKey'])) {
154 2
                $content = $this->cache->fetch($this->options['storeKey']);
155 1
            }
156
157 6
            $request = new Request('GET', $input);
158 6
            if (empty($content)) {
159 4
                $content = $this->fetchFile($request);
160 2
            }
161
162
            // store current host (name or ip) serving the API. This MUST be the host only and does not include the
163
            // scheme nor sub-paths. It MAY include a port. If the host is not included, the host serving the
164
            // documentation is to be used (including the port)
165 6
            $fallbackHost = array();
166 6
            $fallbackHost['host'] = sprintf(
167 6
                '%s://%s:%d',
168 6
                $request->getUri()->getScheme(),
169 6
                $request->getUri()->getHost(),
170 6
                $request->getUri()->getPort()
171 3
            );
172
173 6
            if ($this->strategy->supports($content)) {
174 4
                $retVal = $this->strategy->process($content, $fallbackHost);
175 2
            }
176 3
        }
177
178 6
        return $retVal;
179
    }
180
181
    /**
182
     * fetch file from remote destination
183
     *
184
     * @param RequestInterface $request request
185
     *
186
     * @return string
187
     */
188 4
    private function fetchFile(RequestInterface $request)
189
    {
190 4
        $content = "{}";
191
        try {
192 4
            $response = $this->client->send($request);
193 4
            $content = (string) $response->getBody();
194 4
            if (isset($this->cache)) {
195 2
                $this->cache->save($this->options['storeKey'], $content, $this->cacheLifetime);
196
            }
197 2
        } catch (RequestException $e) {
198
            $this->logger->info(
199
                "Unable to fetch File!",
200
                [
201
                    "message" => $e->getMessage(),
202
                    "url" => $request->getRequestTarget(),
203
                    "code" => (!empty($e->getResponse())? $e->getResponse()->getStatusCode() : 500)
204
                ]
205
            );
206
        }
207
208 4
        return $content;
209
    }
210
}
211