Skip to content

Commit

Permalink
Merge pull request #142 from VeliovGroup/dev
Browse files Browse the repository at this point in the history
v1.6.3
- Compatibility with [email protected]
- Update NPM dependency for `request` package to `2.73.0`
- Implement #141
  • Loading branch information
dr-dimitru authored Jul 11, 2016
2 parents b011a5e + 0080dc8 commit 035886a
Show file tree
Hide file tree
Showing 9 changed files with 578 additions and 596 deletions.
971 changes: 429 additions & 542 deletions .npm/package/npm-shrinkwrap.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/.meteor/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dev_bundle
local
2 changes: 1 addition & 1 deletion demo/.meteor/release
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[email protected].1
[email protected].4
44 changes: 22 additions & 22 deletions demo/.meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,30 @@ aldeed:[email protected]
[email protected]
arillo:[email protected]
[email protected]
[email protected].10
[email protected].3
[email protected].11
[email protected].4
[email protected]_1
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected].5_1
[email protected].6
[email protected]
[email protected]
cfs:[email protected]
[email protected]
[email protected].2_1
[email protected].3
[email protected]
[email protected].8_1
[email protected].9
[email protected]
[email protected]
[email protected].8_1
[email protected].9
[email protected]
[email protected]
[email protected].6_1
[email protected].11_1
[email protected].7
[email protected].12
[email protected]
[email protected]
[email protected]
Expand All @@ -46,49 +46,49 @@ [email protected]
[email protected]
[email protected]
[email protected]
[email protected].7
[email protected].8
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected].13_1
[email protected].14
[email protected]
mdg:[email protected]
[email protected].15_1
[email protected].16
[email protected]
[email protected]
meteorhacks:[email protected]
[email protected].12_1
[email protected].12_1
[email protected].13
[email protected].13
[email protected]
[email protected]
[email protected]
[email protected]
[email protected].4
[email protected].4_1
[email protected].5
[email protected].5
momentjs:[email protected]
[email protected]_1
[email protected]
mquandalle:[email protected]
mquandalle:[email protected]
mrt:[email protected]
[email protected].44_1
[email protected].45
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
ostrio:[email protected]
ostrio:[email protected]
ostrio:[email protected].2
ostrio:[email protected].3
ostrio:[email protected]
ostrio:[email protected]
ostrio:[email protected]
ostrio:[email protected]
ostrio:[email protected]
perak:[email protected]
[email protected].2_1
[email protected].3
raix:[email protected]
[email protected]
[email protected]
Expand All @@ -102,15 +102,15 @@ [email protected]
simple:[email protected]
[email protected]
[email protected]
[email protected].7_1
[email protected].7_1
[email protected].12_1
[email protected].8
[email protected].8
[email protected].13
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected].9_1
[email protected].10
[email protected]
zimme:[email protected]
17 changes: 17 additions & 0 deletions docs/constructor.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@
</td>
<td></td>
</tr>
<tr>
<td align="right">
<code>config.responseHeaders</code> {<em>Object</em>|<em>Function</em>}
</td>
<td>
Server
</td>
<td>
Allows to change default response headers
</td>
<td>
<a href="https://github.com/VeliovGroup/Meteor-Files/wiki/Custom-Responce-Headers#default-function">Default <em>Function</em></a>
</td>
<td>
We recommend to keep original function structure, with your modifications, see <a href="https://github.com/VeliovGroup/Meteor-Files/wiki/Custom-Responce-Headers#adding-custom-header-example">example altering default headers</a>
</td>
</tr>
<tr>
<td align="right">
<code>config.throttle</code> {<em>Number</em>|<em>false</em>}
Expand Down
62 changes: 62 additions & 0 deletions docs/custom-response-headers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#### `FilesCollection` `config.responseHeaders` option (*passed into [Constructor](https://github.com/VeliovGroup/Meteor-Files/wiki/Constructor)*)
Allows to change default response headers.

##### Default function:
We recommend to keep original function structure, with your modifications
```javascript
function responseHeaders (responseCode, fileRef, versionRef) {
var headers = {};
switch (responseCode) {
case '206':
headers['Pragma'] = 'private';
headers['Trailer'] = 'expires';
headers['Transfer-Encoding'] = 'chunked';
break;
case '400':
headers['Cache-Control'] = 'no-cache';
break;
case '416':
headers['Content-Range'] = "bytes */" + versionRef.size;
}
headers['Connection'] = 'keep-alive';
headers['Content-Type'] = versionRef.type || 'application/octet-stream';
headers['Accept-Ranges'] = 'bytes';
return headers;
};
```

##### Adding custom header example:
We recommend to pass `responseHeaders` as a <em>Function</em>, response headers __should be conditional__
```javascript
// As function (keep original function with additions):
var Uploads = new FilesCollection({
responseHeaders: function(responseCode, fileRef, versionRef, version) {
var headers = {};
switch (responseCode) {
case '206':
headers['Pragma'] = 'private';
headers['Trailer'] = 'expires';
headers['Transfer-Encoding'] = 'chunked';
break;
case '400':
headers['Cache-Control'] = 'no-cache';
break;
case '416':
headers['Content-Range'] = "bytes */" + versionRef.size;
}
headers['Connection'] = 'keep-alive';
headers['Content-Type'] = versionRef.type || 'application/octet-stream';
headers['Accept-Ranges'] = 'bytes';
headers['Access-Control-Allow-Origin'] = '*';// <-- Custom header
return headers;
}
});

// As object (not recommended):
var Uploads = new FilesCollection({
responseHeaders: {
Connection: 'keep-alive',
'Access-Control-Allow-Origin': '*'
}
});
```
43 changes: 29 additions & 14 deletions files.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ fixJSONStringify = (obj) ->
@param config.parentDirPermissions {Number} - [Server] Permissions which will be set to parent directory of uploaded files (octal), like: `611` or `0o777`. Default: 0755
@param config.storagePath {String|Function} - [Server] Storage path on file system
@param config.cacheControl {String} - [Server] Default `Cache-Control` header
@param config.responseHeaders {Object|Function} - [Server] Custom response headers, if function is passed, must return Object
@param config.throttle {Number} - [Server] bps throttle threshold
@param config.downloadRoute {String} - [Both] Server Route used to retrieve files
@param config.collection {Mongo.Collection} - [Both] Mongo Collection Instance
Expand All @@ -445,7 +446,7 @@ class FilesCollection
events.EventEmitter.call @
else
EventEmitter.call @
{storagePath, @collection, @collectionName, @downloadRoute, @schema, @chunkSize, @namingFunction, @debug, @onbeforeunloadMessage, @permissions, @parentDirPermissions, @allowClientCode, @onBeforeUpload, @integrityCheck, @protected, @public, @strict, @downloadCallback, @cacheControl, @throttle, @onAfterUpload, @onAfterRemove, @interceptDownload, @onBeforeRemove, @continueUploadTTL} = config if config
{storagePath, @collection, @collectionName, @downloadRoute, @schema, @chunkSize, @namingFunction, @debug, @onbeforeunloadMessage, @permissions, @parentDirPermissions, @allowClientCode, @onBeforeUpload, @integrityCheck, @protected, @public, @strict, @downloadCallback, @cacheControl, @responseHeaders, @throttle, @onAfterUpload, @onAfterRemove, @interceptDownload, @onBeforeRemove, @continueUploadTTL} = config if config

self = @
cookie = new Cookies()
Expand Down Expand Up @@ -483,6 +484,7 @@ class FilesCollection
delete @downloadCallback
delete @interceptDownload
delete @continueUploadTTL
delete @responseHeaders

if _.has(Package, 'accounts-base')
setTokenCookie = ->
Expand Down Expand Up @@ -521,6 +523,22 @@ class FilesCollection
@_currentUploads ?= {}
@downloadCallback ?= false
@continueUploadTTL ?= 10800
@responseHeaders ?= (responseCode, fileRef, versionRef) ->
headers = {}
switch responseCode
when '206'
headers['Pragma'] = 'private'
headers['Trailer'] = 'expires'
headers['Transfer-Encoding'] = 'chunked'
when '400'
headers['Cache-Control'] = 'no-cache'
when '416'
headers['Content-Range'] = "bytes */#{versionRef.size}"

headers['Connection'] = 'keep-alive'
headers['Content-Type'] = versionRef.type or 'application/octet-stream'
headers['Accept-Ranges'] = 'bytes'
return headers

if @public and not storagePath
throw new Meteor.Error 500, "[FilesCollection.#{@collectionName}] \"storagePath\" must be set on \"public\" collections! Note: \"storagePath\" must be equal on be inside of your web/proxy-server (absolute) root."
Expand Down Expand Up @@ -560,6 +578,7 @@ class FilesCollection
check @downloadCallback, Match.OneOf false, Function
check @interceptDownload, Match.OneOf false, Function
check @continueUploadTTL, Number
check @responseHeaders, Match.OneOf Object, Function

@_preCollection = new Mongo.Collection '__pre_' + @collectionName
@_preCollection._ensureIndex {'createdAt': 1}, {expireAfterSeconds: @continueUploadTTL, background: true}
Expand Down Expand Up @@ -1994,11 +2013,7 @@ class FilesCollection
dispositionName = "filename=\"#{encodeURIComponent(fileRef.name)}\"; filename=*UTF-8\"#{encodeURIComponent(fileRef.name)}\"; "
dispositionEncoding = 'charset=utf-8'

http.response.setHeader 'Content-Type', vRef.type
http.response.setHeader 'Content-Disposition', dispositionType + dispositionName + dispositionEncoding
http.response.setHeader 'Accept-Ranges', 'bytes'
http.response.setHeader 'Last-Modified', fileRef?.updatedAt?.toUTCString() if fileRef?.updatedAt?.toUTCString()
http.response.setHeader 'Connection', 'keep-alive'

if http.request.headers.range and not force200
partiral = true
Expand All @@ -2022,16 +2037,12 @@ class FilesCollection
reqRange.end = start + take

reqRange.end = vRef.size - 1 if ((start + take) >= vRef.size)
http.response.setHeader 'Pragma', 'private'
http.response.setHeader 'Expires', new Date(+new Date + 1000*32400).toUTCString()
http.response.setHeader 'Cache-Control', 'private, maxage=10800, s-maxage=32400'

if self.strict and (reqRange.start >= (vRef.size - 1) or reqRange.end > (vRef.size - 1))
responseType = '416'
else
responseType = '206'
else
http.response.setHeader 'Cache-Control', self.cacheControl
responseType = '200'

streamErrorHandler = (error) ->
Expand All @@ -2040,13 +2051,20 @@ class FilesCollection
console.error "[FilesCollection] [serve(#{vRef.path}, #{version})] [500]", error if self.debug
return

headers = if _.isFunction(self.responseHeaders) then self.responseHeaders(responseType, fileRef, vRef, version) else self.responseHeaders

unless headers['Cache-Control']
http.response.setHeader 'Cache-Control', self.cacheControl

for key, value of headers
http.response.setHeader key, value

switch responseType
when '400'
console.warn "[FilesCollection] [serve(#{vRef.path}, #{version})] [400] Content-Length mismatch!" if self.debug
text = 'Content-Length mismatch!'
http.response.writeHead 400,
'Content-Type': 'text/plain'
'Cache-Control': 'no-cache'
'Content-Length': text.length
http.response.end text
break
Expand All @@ -2055,8 +2073,7 @@ class FilesCollection
break
when '416'
console.warn "[FilesCollection] [serve(#{vRef.path}, #{version})] [416] Content-Range is not specified!" if self.debug
http.response.writeHead 416,
'Content-Range': "bytes */#{vRef.size}"
http.response.writeHead 416
http.response.end()
break
when '200'
Expand All @@ -2076,8 +2093,6 @@ class FilesCollection
when '206'
console.info "[FilesCollection] [serve(#{vRef.path}, #{version})] [206]" if self.debug
http.response.setHeader 'Content-Range', "bytes #{reqRange.start}-#{reqRange.end}/#{vRef.size}"
http.response.setHeader 'Trailer', 'expires'
http.response.setHeader 'Transfer-Encoding', 'chunked'
stream = readableStream or fs.createReadStream vRef.path, {start: reqRange.start, end: reqRange.end}
http.response.writeHead 206 if readableStream
stream.on('open', ->
Expand Down
Loading

0 comments on commit 035886a

Please sign in to comment.