diff options
author | Robin Appelman <robin@icewind.nl> | 2022-04-07 16:08:38 +0300 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2022-04-13 15:21:12 +0300 |
commit | 59c4e28885e689c683d599ff97782f1ccc5731e1 (patch) | |
tree | 6f9162591b3ec8cf9c35f28258c70ec66a614acb | |
parent | c66683860324499a41dc8eb777da01d1d7e0de1d (diff) |
stricter types
Signed-off-by: Robin Appelman <robin@icewind.nl>
-rw-r--r-- | js/settings.js | 4 | ||||
-rw-r--r-- | lib/ICAP/ICAPRequest.php | 4 | ||||
-rw-r--r-- | lib/ICAP/IcapResponse.php | 52 | ||||
-rw-r--r-- | lib/ICAP/IcapResponseStatus.php | 48 | ||||
-rw-r--r-- | lib/ICAP/ResponseParser.php | 28 | ||||
-rw-r--r-- | lib/Scanner/ICAP.php | 6 |
6 files changed, 119 insertions, 23 deletions
diff --git a/js/settings.js b/js/settings.js index 3b4de2a..f25444c 100644 --- a/js/settings.js +++ b/js/settings.js @@ -208,7 +208,7 @@ $(document).ready(function() { av_mode_show_options(str, 'slow'); }); - let icapPresets = { + const icapPresets = { clamav: { service: 'avscan', header: 'X-Infection-Found', @@ -219,7 +219,7 @@ $(document).ready(function() { } } $('#av_icap_preset').on('change', function(e) { - var preset = e.target.value; + const preset = e.target.value; if (preset !== 'none') { $('#av_icap_service').val(icapPresets[preset].service); $('#av_icap_header').val(icapPresets[preset].header); diff --git a/lib/ICAP/ICAPRequest.php b/lib/ICAP/ICAPRequest.php index f67796d..2b3fc97 100644 --- a/lib/ICAP/ICAPRequest.php +++ b/lib/ICAP/ICAPRequest.php @@ -73,11 +73,11 @@ class ICAPRequest { fwrite($this->stream, $request); } - public function write(string $data) { + public function write(string $data): void { fwrite($this->stream, dechex(strlen($data)) . "\r\n" . $data . "\r\n"); } - public function finish(): array { + public function finish(): IcapResponse { fwrite($this->stream, "0\r\n\r\n"); return (new ResponseParser())->read_response($this->stream); } diff --git a/lib/ICAP/IcapResponse.php b/lib/ICAP/IcapResponse.php new file mode 100644 index 0000000..518ccce --- /dev/null +++ b/lib/ICAP/IcapResponse.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Files_Antivirus\ICAP; + +class IcapResponse { + private IcapResponseStatus $status; + private array $headers; + private array $responseHeaders; + + public function __construct( + IcapResponseStatus $status, + array $headers, + array $responseHeaders + ) { + $this->status = $status; + $this->headers = $headers; + $this->responseHeaders = $responseHeaders; + } + + public function getStatus(): IcapResponseStatus { + return $this->status; + } + + public function getIcapHeaders(): array { + return $this->headers; + } + + public function getResponseHeaders(): array { + return $this->responseHeaders; + } +} diff --git a/lib/ICAP/IcapResponseStatus.php b/lib/ICAP/IcapResponseStatus.php new file mode 100644 index 0000000..bc019c8 --- /dev/null +++ b/lib/ICAP/IcapResponseStatus.php @@ -0,0 +1,48 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Files_Antivirus\ICAP; + +class IcapResponseStatus { + private string $version; + private int $code; + private string $status; + + public function __construct(string $version, int $code, string $status) { + $this->version = $version; + $this->code = $code; + $this->status = $status; + } + + public function getVersion(): string { + return $this->version; + } + + public function getCode(): int { + return $this->code; + } + + public function getStatus(): string { + return $this->status; + } +} diff --git a/lib/ICAP/ResponseParser.php b/lib/ICAP/ResponseParser.php index a58d0a5..7526f46 100644 --- a/lib/ICAP/ResponseParser.php +++ b/lib/ICAP/ResponseParser.php @@ -28,16 +28,16 @@ use \RuntimeException; class ResponseParser { /** * @param resource $stream - * @return array + * @return IcapResponse */ - public function read_response($stream): array { + public function read_response($stream): IcapResponse { $headers = []; $resHdr = []; - $protocol = $this->readIcapStatusLine($stream); + $status = $this->readIcapStatusLine($stream); // McAfee seems to not properly close the socket once all response bytes are sent to the client // So if ICAP status is 204 we just stop reading - if ($protocol['code'] !== 204) { + if ($status->getCode() !== 204) { $headers = $this->readHeaders($stream); if (isset($headers['Encapsulated'])) { $resHdr = $this->parseResHdr($stream, $headers['Encapsulated']); @@ -45,24 +45,20 @@ class ResponseParser { } fclose($stream); - return [ - 'protocol' => $protocol, - 'headers' => $headers, - 'body' => ['res-hdr' => $resHdr] - ]; + return new IcapResponse($status, $headers, $resHdr); } - private function readIcapStatusLine($stream): array { + /** + * @param resource $stream + * @return IcapResponseStatus + */ + private function readIcapStatusLine($stream): IcapResponseStatus { $icapHeader = \trim(\fgets($stream)); $numValues = \sscanf($icapHeader, "ICAP/%d.%d %d %s", $v1, $v2, $code, $status); if ($numValues !== 4) { throw new RuntimeException("Unknown ICAP response: \"$icapHeader\""); } - return [ - 'protocolVersion' => "$v1.$v2", - 'code' => $code, - 'status' => $status, - ]; + return new IcapResponseStatus("$v1.$v2", (int)$code, $status); } private function parseResHdr($stream, string $headerValue): array { @@ -101,7 +97,7 @@ class ResponseParser { return $headers; } - private function parseEncapsulatedHeaders(string $headerString) : array { + private function parseEncapsulatedHeaders(string $headerString): array { $headers = []; $split = \preg_split('/\r?\n/', \trim($headerString)); $statusLine = \array_shift($split); diff --git a/lib/Scanner/ICAP.php b/lib/Scanner/ICAP.php index 4c94f9d..617554b 100644 --- a/lib/Scanner/ICAP.php +++ b/lib/Scanner/ICAP.php @@ -85,19 +85,19 @@ class ICAP extends ScannerBase { protected function scanBuffer() { $this->flushBuffer(); $response = $this->request->finish(); - $code = (int)$response['protocol']['code'] ?? 500; + $code = $response->getStatus()->getCode(); $this->status->setNumericStatus(Status::SCANRESULT_CLEAN); if ($code === 200 || $code === 204) { // c-icap/clamav reports this header - $virus = $response['headers'][$this->virusHeader] ?? false; + $virus = $response->getIcapHeaders()[$this->virusHeader] ?? false; if ($virus) { $this->status->setNumericStatus(Status::SCANRESULT_INFECTED); $this->status->setDetails($virus); } // kaspersky(pre 2020 product editions) and McAfee handling - $respHeader = $response['body']['res-hdr']['HTTP_STATUS'] ?? ''; + $respHeader = $response->getResponseHeaders()['HTTP_STATUS'] ?? ''; if (\strpos($respHeader, '403 Forbidden') || \strpos($respHeader, '403 VirusFound')) { $this->status->setNumericStatus(Status::SCANRESULT_INFECTED); } |