Skip to content

Commit f169616

Browse files
committed
PHPLIB-319: Added 'disableMD5' option as GridFS MD5 digest must be optional
1 parent baf85f4 commit f169616

8 files changed

+154
-6
lines changed

docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-option.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ interface: phpmethod
1717
operation: ~
1818
optional: true
1919
---
20+
arg_name: option
21+
name: disableMD5
22+
type: boolean
23+
description: |
24+
Whether to disable automatic MD5 generation when storing files.
25+
26+
Defaults to ``false``.
27+
interface: phpmethod
28+
operation: ~
29+
optional: true
30+
---
2031
source:
2132
file: apiargs-common-option.yaml
2233
ref: readConcern

docs/includes/apiargs-MongoDBGridFSBucket-common-option.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ operation: ~
1818
optional: true
1919
---
2020
arg_name: option
21+
name: disableMD5
22+
type: boolean
23+
description: |
24+
Whether to disable automatic MD5 generation when storing files.
25+
26+
Defaults to ``false``.
27+
interface: phpmethod
28+
operation: ~
29+
optional: true
30+
---
31+
arg_name: option
2132
name: metadata
2233
type: array|object
2334
description: |

docs/includes/apiargs-MongoDBGridFSBucket-method-construct-option.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ interface: phpmethod
1717
operation: ~
1818
optional: true
1919
---
20+
arg_name: option
21+
name: disableMD5
22+
type: boolean
23+
description: |
24+
Whether to disable automatic MD5 generation when storing files.
25+
26+
Defaults to ``false``.
27+
interface: phpmethod
28+
operation: ~
29+
optional: true
30+
---
2031
source:
2132
file: apiargs-common-option.yaml
2233
ref: readConcern

docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-option.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ source:
66
file: apiargs-MongoDBGridFSBucket-common-option.yaml
77
ref: chunkSizeBytes
88
---
9+
source:
10+
file: apiargs-MongoDBGridFSBucket-common-option.yaml
11+
ref: disableMD5
12+
---
913
source:
1014
file: apiargs-MongoDBGridFSBucket-common-option.yaml
1115
ref: metadata

docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-option.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ source:
66
file: apiargs-MongoDBGridFSBucket-common-option.yaml
77
ref: chunkSizeBytes
88
---
9+
source:
10+
file: apiargs-MongoDBGridFSBucket-common-option.yaml
11+
ref: disableMD5
12+
---
913
source:
1014
file: apiargs-MongoDBGridFSBucket-common-option.yaml
1115
ref: metadata

src/GridFS/Bucket.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Bucket
5151
private $databaseName;
5252
private $manager;
5353
private $bucketName;
54+
private $disableMD5;
5455
private $chunkSizeBytes;
5556
private $readConcern;
5657
private $readPreference;
@@ -68,6 +69,9 @@ class Bucket
6869
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
6970
* 261120 (i.e. 255 KiB).
7071
*
72+
* * disableMD5 (boolean): When true, no MD5 sum will be generated for
73+
* each stored file. Defaults to "false".
74+
*
7175
* * readConcern (MongoDB\Driver\ReadConcern): Read concern.
7276
*
7377
* * readPreference (MongoDB\Driver\ReadPreference): Read preference.
@@ -100,6 +104,10 @@ public function __construct(Manager $manager, $databaseName, array $options = []
100104
throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
101105
}
102106

107+
if (isset($options['disableMD5']) && ! is_bool($options['disableMD5'])) {
108+
throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
109+
}
110+
103111
if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
104112
throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], 'MongoDB\Driver\ReadConcern');
105113
}
@@ -120,6 +128,7 @@ public function __construct(Manager $manager, $databaseName, array $options = []
120128
$this->databaseName = (string) $databaseName;
121129
$this->bucketName = $options['bucketName'];
122130
$this->chunkSizeBytes = $options['chunkSizeBytes'];
131+
$this->disableMD5 = isset($options['disableMD5']) ? $options['disableMD5'] : false;
123132
$this->readConcern = isset($options['readConcern']) ? $options['readConcern'] : $this->manager->getReadConcern();
124133
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
125134
$this->typeMap = isset($options['typeMap']) ? $options['typeMap'] : self::$defaultTypeMap;
@@ -470,6 +479,9 @@ public function openDownloadStreamByName($filename, array $options = [])
470479
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
471480
* bucket's chunk size.
472481
*
482+
* * disableMD5 (boolean): When true, no MD5 sum will be generated for
483+
* the stored file. Defaults to "false".
484+
*
473485
* * metadata (document): User data for the "metadata" field of the files
474486
* collection document.
475487
*

src/GridFS/WritableStream.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ class WritableStream
3636
private $buffer = '';
3737
private $chunkOffset = 0;
3838
private $chunkSize;
39+
private $disableMD5;
3940
private $collectionWrapper;
40-
private $ctx;
4141
private $file;
42+
private $hashCtx;
4243
private $isClosed = false;
4344
private $length = 0;
4445

@@ -56,6 +57,9 @@ class WritableStream
5657
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
5758
* 261120 (i.e. 255 KiB).
5859
*
60+
* * disableMD5 (boolean): When true, no MD5 sum will be generated.
61+
* Defaults to "false".
62+
*
5963
* * contentType (string): DEPRECATED content type to be stored with the
6064
* file. This information should now be added to the metadata.
6165
*
@@ -86,6 +90,10 @@ public function __construct(CollectionWrapper $collectionWrapper, $filename, arr
8690
throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
8791
}
8892

93+
if (isset($options['disableMD5']) && ! is_bool($options['disableMD5'])) {
94+
throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
95+
}
96+
8997
if (isset($options['contentType']) && ! is_string($options['contentType'])) {
9098
throw InvalidArgumentException::invalidType('"contentType" option', $options['contentType'], 'string');
9199
}
@@ -96,7 +104,11 @@ public function __construct(CollectionWrapper $collectionWrapper, $filename, arr
96104

97105
$this->chunkSize = $options['chunkSizeBytes'];
98106
$this->collectionWrapper = $collectionWrapper;
99-
$this->ctx = hash_init('md5');
107+
$this->disableMD5 = isset($options['disableMD5']) ? $options['disableMD5'] : false;
108+
109+
if ( ! $this->disableMD5) {
110+
$this->hashCtx = hash_init('md5');
111+
}
100112

101113
$this->file = [
102114
'_id' => $options['_id'],
@@ -219,12 +231,14 @@ private function abort()
219231

220232
private function fileCollectionInsert()
221233
{
222-
$md5 = hash_final($this->ctx);
223-
224234
$this->file['length'] = $this->length;
225-
$this->file['md5'] = $md5;
226235
$this->file['uploadDate'] = new UTCDateTime;
227236

237+
if ( ! $this->disableMD5) {
238+
$md5 = hash_final($this->hashCtx);
239+
$this->file['md5'] = $md5;
240+
}
241+
228242
try {
229243
$this->collectionWrapper->insertFile($this->file);
230244
} catch (DriverRuntimeException $e) {
@@ -251,7 +265,9 @@ private function insertChunkFromBuffer()
251265
'data' => new Binary($data, Binary::TYPE_GENERIC),
252266
];
253267

254-
hash_update($this->ctx, $data);
268+
if ( ! $this->disableMD5) {
269+
hash_update($this->hashCtx, $data);
270+
}
255271

256272
try {
257273
$this->collectionWrapper->insertChunk($chunk);

tests/GridFS/spec-tests/upload.json

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,85 @@
382382
}
383383
]
384384
}
385+
},
386+
{
387+
"description": "Upload when length is 0 sans MD5",
388+
"act": {
389+
"operation": "upload",
390+
"arguments": {
391+
"filename": "filename",
392+
"source": {
393+
"$hex": ""
394+
},
395+
"options": {
396+
"chunkSizeBytes": 4,
397+
"disableMD5": true
398+
}
399+
}
400+
},
401+
"assert": {
402+
"result": "&result",
403+
"data": [
404+
{
405+
"insert": "expected.files",
406+
"documents": [
407+
{
408+
"_id": "*result",
409+
"length": 0,
410+
"chunkSize": 4,
411+
"uploadDate": "*actual",
412+
"filename": "filename"
413+
}
414+
]
415+
}
416+
]
417+
}
418+
},
419+
{
420+
"description": "Upload when length is 1 sans MD5",
421+
"act": {
422+
"operation": "upload",
423+
"arguments": {
424+
"filename": "filename",
425+
"source": {
426+
"$hex": "11"
427+
},
428+
"options": {
429+
"chunkSizeBytes": 4,
430+
"disableMD5": true
431+
}
432+
}
433+
},
434+
"assert": {
435+
"result": "&result",
436+
"data": [
437+
{
438+
"insert": "expected.files",
439+
"documents": [
440+
{
441+
"_id": "*result",
442+
"length": 1,
443+
"chunkSize": 4,
444+
"uploadDate": "*actual",
445+
"filename": "filename"
446+
}
447+
]
448+
},
449+
{
450+
"insert": "expected.chunks",
451+
"documents": [
452+
{
453+
"_id": "*actual",
454+
"files_id": "*result",
455+
"n": 0,
456+
"data": {
457+
"$hex": "11"
458+
}
459+
}
460+
]
461+
}
462+
]
463+
}
385464
}
386465
]
387466
}

0 commit comments

Comments
 (0)