|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* (c) Kitodo. Key to digital objects e.V. <[email protected]> |
|
5
|
|
|
* |
|
6
|
|
|
* This file is part of the Kitodo and TYPO3 projects. |
|
7
|
|
|
* |
|
8
|
|
|
* @license GNU General Public License version 3 or later. |
|
9
|
|
|
* For the full copyright and license information, please read the |
|
10
|
|
|
* LICENSE.txt file that was distributed with this source code. |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
namespace Kitodo\Dlf\Plugin\Eid; |
|
14
|
|
|
|
|
15
|
|
|
use Psr\Http\Message\RequestFactoryInterface; |
|
16
|
|
|
use Psr\Http\Message\ResponseInterface; |
|
17
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
|
18
|
|
|
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; |
|
19
|
|
|
use TYPO3\CMS\Core\Http\RequestFactory; |
|
20
|
|
|
use TYPO3\CMS\Core\Http\Response; |
|
21
|
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility; |
|
22
|
|
|
use TYPO3\CMS\Core\Utility\MathUtility; |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* eID image proxy for plugin 'Page View' of the 'dlf' extension |
|
26
|
|
|
* |
|
27
|
|
|
* @author Alexander Bigga <[email protected]> |
|
28
|
|
|
* @package TYPO3 |
|
29
|
|
|
* @subpackage dlf |
|
30
|
|
|
* @access public |
|
31
|
|
|
*/ |
|
32
|
|
|
class PageViewProxy |
|
33
|
|
|
{ |
|
34
|
|
|
/** |
|
35
|
|
|
* @var RequestFactoryInterface |
|
36
|
|
|
*/ |
|
37
|
|
|
protected $requestFactory; |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* @var mixed |
|
41
|
|
|
*/ |
|
42
|
|
|
protected $extConf; |
|
43
|
|
|
|
|
44
|
|
|
public function __construct() |
|
45
|
|
|
{ |
|
46
|
|
|
$this->requestFactory = GeneralUtility::makeInstance(RequestFactory::class); |
|
47
|
|
|
$this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('dlf'); |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
protected function overwriteHeaders(array $headers) |
|
51
|
|
|
{ |
|
52
|
|
|
header_remove(); |
|
53
|
|
|
foreach ($headers as $key => $value) { |
|
54
|
|
|
// The `header()` function should already make sure this is safe |
|
55
|
|
|
// (Won't let $value containing newline pass.) |
|
56
|
|
|
@header("$key: $value"); |
|
|
|
|
|
|
57
|
|
|
} |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
protected function sendJson(int $statusCode, $object): ResponseInterface |
|
61
|
|
|
{ |
|
62
|
|
|
/** @var Response $response */ |
|
63
|
|
|
$response = GeneralUtility::makeInstance(Response::class) |
|
64
|
|
|
->withStatus($statusCode) |
|
65
|
|
|
->withHeader("Content-Type", "application/json"); |
|
66
|
|
|
$response->getBody()->write(json_encode($object)); |
|
67
|
|
|
return $response; |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
protected function getRequestHeaders() |
|
71
|
|
|
{ |
|
72
|
|
|
return [ |
|
73
|
|
|
"User-Agent" => $this->extConf['useragent'] ?? "Kitodo.Presentation Proxy", |
|
74
|
|
|
]; |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** |
|
78
|
|
|
* The main method of the eID script |
|
79
|
|
|
* |
|
80
|
|
|
* @access public |
|
81
|
|
|
* |
|
82
|
|
|
* @param ServerRequestInterface $request |
|
83
|
|
|
* @return ResponseInterface |
|
84
|
|
|
*/ |
|
85
|
|
|
public function main(ServerRequestInterface $request) |
|
86
|
|
|
{ |
|
87
|
|
|
$url = (string) $request->getQueryParams()['url']; |
|
88
|
|
|
|
|
89
|
|
|
if (!GeneralUtility::isValidUrl($url)) { |
|
90
|
|
|
return $this->sendJson(400, [ |
|
91
|
|
|
"message" => "Invalid URL.", |
|
92
|
|
|
]); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
// Originally the header parameter for `GeneralUtility::getUrl()` |
|
96
|
|
|
// Allowed values: |
|
97
|
|
|
// - 0 Don't fetch headers. We'll ignore that. |
|
98
|
|
|
// - 1 Fetch headers and content. We'll follow suit. |
|
99
|
|
|
// - 2 Fetch headers only. We'll follow suit. |
|
100
|
|
|
$header = (int) $request->getQueryParams()['header']; |
|
101
|
|
|
$headerOnly = MathUtility::forceIntegerInRange($header, 0, 2, 0) === 2; |
|
102
|
|
|
|
|
103
|
|
|
$httpMethod = $headerOnly ? 'HEAD' : 'GET'; |
|
104
|
|
|
try { |
|
105
|
|
|
$response = $this->requestFactory->request($url, $httpMethod, [ |
|
|
|
|
|
|
106
|
|
|
'headers' => $this->getRequestHeaders(), |
|
107
|
|
|
|
|
108
|
|
|
// For performance, don't download content up-front. Rather, we'll |
|
109
|
|
|
// download and upload simultaneously. |
|
110
|
|
|
// https://docs.guzzlephp.org/en/6.5/request-options.html#stream |
|
111
|
|
|
'stream' => true, |
|
112
|
|
|
|
|
113
|
|
|
// Don't throw exceptions when a non-success status code is |
|
114
|
|
|
// received. We handle these manually. |
|
115
|
|
|
'http_errors' => false, |
|
116
|
|
|
]); |
|
117
|
|
|
} catch (\Exception $e) { |
|
118
|
|
|
return $this->sendJson(500, [ |
|
119
|
|
|
"message" => "Could not fetch resource of given URL.", |
|
120
|
|
|
]); |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
http_response_code($response->getStatusCode()); |
|
124
|
|
|
|
|
125
|
|
|
$this->overwriteHeaders([ |
|
126
|
|
|
"Access-Control-Allow-Methods" => "GET", |
|
127
|
|
|
"Access-Control-Allow-Origin" => $request->getHeaderLine('Origin') ? : '*', |
|
128
|
|
|
"Access-Control-Max-Age" => "86400", |
|
129
|
|
|
"Content-Type" => $response->getHeader("Content-Type")[0], |
|
130
|
|
|
"Last-Modified" => $response->getHeader("Last-Modified")[0], |
|
131
|
|
|
]); |
|
132
|
|
|
|
|
133
|
|
|
if (!$headerOnly) { |
|
134
|
|
|
// Disable output buffering |
|
135
|
|
|
ob_end_flush(); |
|
136
|
|
|
|
|
137
|
|
|
// Stream proxied content in chunks of 8KB |
|
138
|
|
|
$outStream = $response->getBody(); |
|
139
|
|
|
while (!$outStream->eof()) { |
|
140
|
|
|
echo $outStream->read(8 * 1024); |
|
141
|
|
|
} |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
exit; |
|
|
|
|
|
|
145
|
|
|
} |
|
146
|
|
|
} |
|
147
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.