Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/files_antivirus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2022-03-18 18:37:38 +0300
committerRobin Appelman <robin@icewind.nl>2022-04-13 15:21:12 +0300
commit1823ab0316fd75a09bef6959a775ef47d48be530 (patch)
tree2feeac5743b827ad6a3dc385185d49d9f8ff683f
parent1292675de73eb2fd3b29ed713cbd152974cd6c9e (diff)
chunked icap
Signed-off-by: Robin Appelman <robin@icewind.nl>
-rw-r--r--lib/ICAP/ICAPClient.php14
-rw-r--r--lib/ICAP/ICAPRequest.php10
-rw-r--r--lib/Scanner/ICAP.php27
3 files changed, 30 insertions, 21 deletions
diff --git a/lib/ICAP/ICAPClient.php b/lib/ICAP/ICAPClient.php
index 1e872e2..313cbcd 100644
--- a/lib/ICAP/ICAPClient.php
+++ b/lib/ICAP/ICAPClient.php
@@ -29,8 +29,6 @@ class ICAPClient {
private string $host;
private int $port;
- const USER_AGENT = 'NC-ICAP-CLIENT/0.5.0';
-
/**
* Constructor
*
@@ -56,7 +54,7 @@ class ICAPClient {
);
if (!$stream) {
- throw new \Exception(
+ throw new RuntimeException(
"Cannot connect to \"tcp://{$this->host}:{$this->port}\": $errorMessage (code $errorCode)"
);
}
@@ -68,12 +66,12 @@ class ICAPClient {
* Send REQMOD request
*
* @param string $service ICAP service
- * @param array $body Request body data
- * @return array Response array
- * @throws RuntimeException
+ * @param array $headers
+ * @param string $requestHeader
+ * @return ICAPRequest Response array
*/
- public function reqmod(string $service, array $headers, string $requestHeader, int $bodyLength): ICAPRequest {
+ public function reqmod(string $service, array $headers, string $requestHeader): ICAPRequest {
$stream = $this->connect();
- return new ICAPRequest($stream, $this->host, $service, 'REQMOD', $headers, $requestHeader, $bodyLength);
+ return new ICAPRequest($stream, $this->host, $service, 'REQMOD', $headers, $requestHeader);
}
}
diff --git a/lib/ICAP/ICAPRequest.php b/lib/ICAP/ICAPRequest.php
index 2bec713..f4c97b0 100644
--- a/lib/ICAP/ICAPRequest.php
+++ b/lib/ICAP/ICAPRequest.php
@@ -27,9 +27,9 @@ class ICAPRequest {
const USER_AGENT = 'NC-ICAP-CLIENT/0.5.0';
/** @var resource */
- private $stream;
+ public $stream;
- public function __construct($stream, string $host, string $service, string $method, array $headers, string $requestHeader, int $bodyLength) {
+ public function __construct($stream, string $host, string $service, string $method, array $headers, string $requestHeader) {
$this->stream = $stream;
if (!array_key_exists('Host', $headers)) {
@@ -62,18 +62,16 @@ class ICAPRequest {
$request .= "\r\n";
$request .= $requestHeader;
- $request .= dechex($bodyLength);
- $request .= "\r\n";
fwrite($this->stream, $request);
}
public function write(string $data) {
- fwrite($this->stream, $data);
+ fwrite($this->stream, dechex(strlen($data)) . "\r\n" . $data . "\r\n");
}
public function finish(): array {
- fwrite($this->stream, "\r\n0\r\n\r\n");
+ fwrite($this->stream, "0\r\n\r\n");
return (new ResponseParser())->read_response($this->stream);
}
}
diff --git a/lib/Scanner/ICAP.php b/lib/Scanner/ICAP.php
index 5a0c88b..2a0efe9 100644
--- a/lib/Scanner/ICAP.php
+++ b/lib/Scanner/ICAP.php
@@ -25,6 +25,7 @@ namespace OCA\Files_Antivirus\Scanner;
use OCA\Files_Antivirus\AppConfig;
use OCA\Files_Antivirus\ICAP\ICAPClient;
+use OCA\Files_Antivirus\ICAP\ICAPRequest;
use OCA\Files_Antivirus\Status;
use OCA\Files_Antivirus\StatusFactory;
use OCP\Http\Client\IClientService;
@@ -32,6 +33,7 @@ use OCP\ILogger;
class ICAP extends ScannerBase {
private ICAPClient $icapClient;
+ private ?ICAPRequest $request;
public function __construct(
AppConfig $config,
@@ -52,17 +54,28 @@ class ICAP extends ScannerBase {
public function initScanner() {
parent::initScanner();
$this->writeHandle = fopen("php://temp", 'w+');
+ $this->request = $this->icapClient->reqmod('req', [
+ 'Allow' => 204,
+ ], "PUT / HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n");
}
- protected function scanBuffer() {
+ protected function writeChunk($chunk) {
+ if (ftell($this->writeHandle) > 1024 * 1024) {
+ $this->flushBuffer();
+ }
+ parent::writeChunk($chunk);
+ }
+
+ private function flushBuffer() {
rewind($this->writeHandle);
$data = stream_get_contents($this->writeHandle);
+ $this->request->write($data);
+ $this->writeHandle = fopen("php://temp", 'w+');
+ }
- $request = $this->icapClient->reqmod('req', [
- 'Allow' => 204
- ], "PUT / HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n", strlen($data));
- $request->write($data);
- $response = $request->finish();
+ protected function scanBuffer() {
+ $this->flushBuffer();
+ $response = $this->request->finish();
$code = (int)$response['protocol']['code'] ?? 500;
$this->status->setNumericStatus(Status::SCANRESULT_CLEAN);
@@ -80,7 +93,7 @@ class ICAP extends ScannerBase {
$this->status->setNumericStatus(Status::SCANRESULT_INFECTED);
}
} else {
- throw new \RuntimeException('AV failed!');
+ throw new \RuntimeException('Invalid response from ICAP server');
}
}