From d2a28e09575bfa1af9878bff02b5928aaa150ad3 Mon Sep 17 00:00:00 2001 From: Yoann Ciabaud Date: Sun, 24 Apr 2016 14:13:42 +0200 Subject: [PATCH 1/3] Make server handling flow.js compatible --- .gitmodules | 6 +++--- flow.js | 1 + package.js | 2 +- resumable | 1 - src/resumable_server.coffee | 22 +++++++++++----------- 5 files changed, 16 insertions(+), 16 deletions(-) create mode 160000 flow.js delete mode 160000 resumable diff --git a/.gitmodules b/.gitmodules index 1de8911..0c50b06 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "resumable"] - path = resumable - url = https://github.com/23/resumable.js.git +[submodule "flow.js"] + path = flow.js + url = https://github.com/flowjs/flow.js diff --git a/flow.js b/flow.js new file mode 160000 index 0000000..b9e5421 --- /dev/null +++ b/flow.js @@ -0,0 +1 @@ +Subproject commit b9e542168c74419ae66b646e7538e9552f1fca2d diff --git a/package.js b/package.js index d755a0c..1b0f4fb 100644 --- a/package.js +++ b/package.js @@ -31,7 +31,7 @@ Package.onUse(function(api) { api.use('mongo@1.1.6', ['server', 'client']); api.use('minimongo@1.0.13', 'server'); api.use('check@1.1.3', ['server', 'client']); - api.addFiles('resumable/resumable.js', 'client'); + api.addFiles('flow/dist/flow.js', 'client'); api.addFiles('src/gridFS.coffee', ['server','client']); api.addFiles('src/server_shared.coffee', 'server'); api.addFiles('src/gridFS_server.coffee', 'server'); diff --git a/resumable b/resumable deleted file mode 160000 index f3085f6..0000000 --- a/resumable +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f3085f690142e1998a3fb92de9df6c2874a80ebd diff --git a/src/resumable_server.coffee b/src/resumable_server.coffee index 39f8462..36fe656 100644 --- a/src/resumable_server.coffee +++ b/src/resumable_server.coffee @@ -126,26 +126,26 @@ if Meteor.isServer lock.on 'timed-out', () -> callback new Meteor.Error "File Lock timed out" lock.on 'error', (err) -> callback err - # Handle HTTP POST requests from Resumable.js + # Handle HTTP POST requests from Resumable.js or Flow.js resumable_post_lookup = (params, query, multipart) -> - return { _id: share.safeObjectID(multipart?.params?.resumableIdentifier) } + return { _id: share.safeObjectID(multipart?.params?.resumableIdentifier || req.multipart?.params?.flowIdentifier) } resumable_post_handler = (req, res, next) -> # This has to be a resumable POST - unless req.multipart?.params?.resumableIdentifier + unless req.multipart?.params?.resumableIdentifier || req.multipart?.params?.flowIdentifier console.error "Missing resumable.js multipart information" res.writeHead(501, share.defaultResponseHeaders) res.end() return resumable = req.multipart.params - resumable.resumableTotalSize = parseInt resumable.resumableTotalSize - resumable.resumableTotalChunks = parseInt resumable.resumableTotalChunks - resumable.resumableChunkNumber = parseInt resumable.resumableChunkNumber - resumable.resumableChunkSize = parseInt resumable.resumableChunkSize - resumable.resumableCurrentChunkSize = parseInt resumable.resumableCurrentChunkSize + resumable.resumableTotalSize = parseInt resumable.resumableTotalSize || resumable.flowTotalSize + resumable.resumableTotalChunks = parseInt resumable.resumableTotalChunks || resumable.flowTotalChunks + resumable.resumableChunkNumber = parseInt resumable.resumableChunkNumber || resumable.flowChunkNumber + resumable.resumableChunkSize = parseInt resumable.resumableChunkSize || resumable.flowChunkSize + resumable.resumableCurrentChunkSize = parseInt resumable.resumableCurrentChunkSize || resumable.flowCurrentChunkSize if req.maxUploadSize > 0 unless resumable.resumableTotalSize <= req.maxUploadSize @@ -214,7 +214,7 @@ if Meteor.isServer res.end()) resumable_get_lookup = (params, query) -> - q = { _id: share.safeObjectID(query.resumableIdentifier) } + q = { _id: share.safeObjectID(query.resumableIdentifier || query.flowIdentifier) } return q # This handles Resumable.js "test GET" requests, that exist to determine @@ -230,8 +230,8 @@ if Meteor.isServer } { length: parseInt query.resumableCurrentChunkSize - 'metadata._Resumable.resumableIdentifier': query.resumableIdentifier - 'metadata._Resumable.resumableChunkNumber': parseInt query.resumableChunkNumber + 'metadata._Resumable.resumableIdentifier': query.resumableIdentifier || query.flowIdentifier + 'metadata._Resumable.resumableChunkNumber': parseInt query.resumableChunkNumber || query.flowChunkNumber } ] From e0b36b5d9f0481b9e69b6d1cc80aaaac5da60f63 Mon Sep 17 00:00:00 2001 From: Yoann Ciabaud Date: Fri, 6 May 2016 16:49:52 +0200 Subject: [PATCH 2/3] Remove resumable client and add flowjs server compatibility --- .versions | 108 ++++++++++++++++++------------------ README.md | 10 ++-- flow.js | 1 - package.js | 10 ++-- src/gridFS_client.coffee | 6 +- src/resumable_client.coffee | 52 ----------------- src/resumable_server.coffee | 4 +- 7 files changed, 67 insertions(+), 124 deletions(-) delete mode 160000 flow.js delete mode 100644 src/resumable_client.coffee diff --git a/.versions b/.versions index 34556da..f6f694e 100644 --- a/.versions +++ b/.versions @@ -1,54 +1,54 @@ -allow-deny@1.0.3 -babel-compiler@6.6.1 -babel-runtime@0.1.7 -base64@1.0.7 -binary-heap@1.0.7 -blaze@2.1.6 -blaze-tools@1.0.7 -boilerplate-generator@1.0.7 -caching-compiler@1.0.3 -callback-hook@1.0.7 -check@1.1.3 -coffeescript@1.0.16 -ddp@1.2.4 -ddp-client@1.2.4 -ddp-common@1.2.4 -ddp-server@1.2.5 -deps@1.0.11 -diff-sequence@1.0.4 -ecmascript@0.4.2 -ecmascript-runtime@0.2.9 -ejson@1.0.10 -geojson-utils@1.0.7 -html-tools@1.0.8 -htmljs@1.0.8 -http@1.1.4 -id-map@1.0.6 -jquery@1.11.7 -local-test:vsivsi:file-collection@1.3.4 -logging@1.0.11 -meteor@1.1.13 -minimongo@1.0.13 -modules@0.5.2 -modules-runtime@0.6.2 -mongo@1.1.6 -mongo-id@1.0.3 -npm-mongo@1.4.42 -observe-sequence@1.0.10 -ordered-dict@1.0.6 -promise@0.6.6 -random@1.0.8 -reactive-var@1.0.8 -retry@1.0.6 -routepolicy@1.0.9 -spacebars@1.0.10 -spacebars-compiler@1.0.10 -test-helpers@1.0.8 -tinytest@1.0.9 -tracker@1.0.12 -ui@1.0.10 -underscore@1.0.7 -url@1.0.8 -vsivsi:file-collection@1.3.4 -webapp@1.2.7 -webapp-hashing@1.0.8 +allow-deny@1.0.4 +babel-compiler@6.6.4 +babel-runtime@0.1.8 +base64@1.0.8 +binary-heap@1.0.8 +blaze@2.1.7 +blaze-tools@1.0.8 +boilerplate-generator@1.0.8 +caching-compiler@1.0.4 +callback-hook@1.0.8 +check@1.2.1 +coffeescript@1.0.17 +ddp@1.2.5 +ddp-client@1.2.7 +ddp-common@1.2.5 +ddp-server@1.2.6 +deps@1.0.12 +diff-sequence@1.0.5 +ecmascript@0.4.3 +ecmascript-runtime@0.2.10 +ejson@1.0.11 +geojson-utils@1.0.8 +html-tools@1.0.9 +htmljs@1.0.9 +http@1.1.5 +id-map@1.0.7 +jquery@1.11.8 +local-test:yciabaud:file-collection-server@1.3.4_5 +logging@1.0.12 +meteor@1.1.14 +minimongo@1.0.16 +modules@0.6.1 +modules-runtime@0.6.3 +mongo@1.1.7 +mongo-id@1.0.4 +npm-mongo@1.4.43 +observe-sequence@1.0.11 +ordered-dict@1.0.7 +promise@0.6.7 +random@1.0.9 +reactive-var@1.0.9 +retry@1.0.7 +routepolicy@1.0.10 +spacebars@1.0.11 +spacebars-compiler@1.0.11 +test-helpers@1.0.9 +tinytest@1.0.10 +tracker@1.0.13 +ui@1.0.11 +underscore@1.0.8 +url@1.0.9 +webapp@1.2.8 +webapp-hashing@1.0.9 +yciabaud:file-collection-server@1.3.4_5 diff --git a/README.md b/README.md index a3518b0..9dbfdcc 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ -# file-collection - -[![Build Status](https://travis-ci.org/vsivsi/meteor-file-collection.svg)](https://travis-ci.org/vsivsi/meteor-file-collection) +# file-collection-server ## Introduction -file-collection is a Meteor.js package that cleanly extends Meteor's Collection metaphor for efficiently dealing with collections of files and their data. File Collections are fully reactive, and if you know how to use Meteor Collections, you already know most of what you need to begin working with this package. +file-collection-server is an experimental fork of [file-collection](https://github.com/vsivsi/meteor-file-collection/) Meteor.js package that cleanly extends Meteor's Collection metaphor for efficiently dealing with collections of files and their data. File Collections are fully reactive, and if you know how to use Meteor Collections, you already know most of what you need to begin working with this package. + +This fork removes the client part of the package to be able to work with different client implementations. Major features: * HTTP upload and download including support for Meteor authentication -* Client and Server integration of [resumable.js](http://resumablejs.com/) for robust chunked uploading +* Server integration of [resumable.js](http://resumablejs.com/) and [flow.js](https://github.com/flowjs/flow.js) for robust chunked uploading * Also compatible with traditional HTTP POST or PUT file uploading * HTTP range requests support random access for resumable downloads, media seeking, etc. * Robust file locking allows safe replacement and removal of files even on a busy server diff --git a/flow.js b/flow.js deleted file mode 160000 index b9e5421..0000000 --- a/flow.js +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b9e542168c74419ae66b646e7538e9552f1fca2d diff --git a/package.js b/package.js index 1b0f4fb..9011651 100644 --- a/package.js +++ b/package.js @@ -4,13 +4,13 @@ ### See included LICENSE file for details. ***************************************************************************/ -var currentVersion = '1.3.4'; +var currentVersion = '1.3.4_5'; Package.describe({ summary: 'Collections that efficiently store files using MongoDB GridFS, with built-in HTTP support', - name: 'vsivsi:file-collection', + name: 'yciabaud:file-collection-server', version: currentVersion, - git: 'https://github.com/vsivsi/meteor-file-collection.git' + git: 'https://github.com/yciabaud/meteor-file-collection.git' }); Npm.depends({ @@ -31,19 +31,17 @@ Package.onUse(function(api) { api.use('mongo@1.1.6', ['server', 'client']); api.use('minimongo@1.0.13', 'server'); api.use('check@1.1.3', ['server', 'client']); - api.addFiles('flow/dist/flow.js', 'client'); api.addFiles('src/gridFS.coffee', ['server','client']); api.addFiles('src/server_shared.coffee', 'server'); api.addFiles('src/gridFS_server.coffee', 'server'); api.addFiles('src/resumable_server.coffee', 'server'); api.addFiles('src/http_access_server.coffee', 'server'); - api.addFiles('src/resumable_client.coffee', 'client'); api.addFiles('src/gridFS_client.coffee', 'client'); api.export('FileCollection'); }); Package.onTest(function (api) { - api.use('vsivsi:file-collection@' + currentVersion, ['server', 'client']); + api.use('yciabaud:file-collection-server@' + currentVersion, ['server', 'client']); api.use('coffeescript@1.0.16', ['server', 'client']); api.use('tinytest@1.0.9', ['server', 'client']); api.use('test-helpers@1.0.8', ['server','client']); diff --git a/src/gridFS_client.coffee b/src/gridFS_client.coffee index 080b541..d3a36a9 100644 --- a/src/gridFS_client.coffee +++ b/src/gridFS_client.coffee @@ -24,14 +24,10 @@ if Meteor.isClient @base = @root @baseURL = options.baseURL ? "/gridfs/#{@root}" + @resumableURL = "#{@baseURL}#{share.resumableBase}" @chunkSize = options.chunkSize ? share.defaultChunkSize super @root + '.files', { idGeneration: 'MONGO' } - # This call sets up the optional support for resumable.js - # See the resumable.coffee file for more information - if options.resumable - share.setup_resumable.bind(@)() - # remove works as-is. No modifications necessary so it currently goes straight to super # Insert only creates an empty (but valid) gridFS file. To put data into it from a client, diff --git a/src/resumable_client.coffee b/src/resumable_client.coffee deleted file mode 100644 index bc75904..0000000 --- a/src/resumable_client.coffee +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################ -# Copyright (C) 2014-2016 by Vaughn Iverson -# fileCollection is free software released under the MIT/X11 license. -# See included LICENSE file for details. -############################################################################ - -if Meteor.isClient - - # This is a polyfill for bind(), added to make phantomjs 1.9.7 work - unless Function.prototype.bind - Function.prototype.bind = (oThis) -> - if typeof this isnt "function" - # closest thing possible to the ECMAScript 5 internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable") - - aArgs = Array.prototype.slice.call arguments, 1 - fToBind = this - fNOP = () -> - fBound = () -> - func = if (this instanceof fNOP and oThis) then this else oThis - return fToBind.apply(func, aArgs.concat(Array.prototype.slice.call(arguments))) - - fNOP.prototype = this.prototype - - fBound.prototype = new fNOP() - return fBound - - share.setup_resumable = () -> - url = "#{@baseURL}#{share.resumableBase}" - url = Meteor.absoluteUrl(url) if Meteor.isCordova - r = new Resumable - target: url - generateUniqueIdentifier: (file) -> "#{new Mongo.ObjectID()}" - fileParameterName: 'file' - chunkSize: @chunkSize - testChunks: true - testMethod: 'HEAD' - permanentErrors: [204, 404, 415, 500, 501] - simultaneousUploads: 3 - maxFiles: undefined - maxFilesErrorCallback: undefined - prioritizeFirstAndLastChunk: false - query: undefined - headers: {} - maxChunkRetries: 5 - withCredentials: true - - unless r.support - console.warn "resumable.js not supported by this Browser, uploads will be disabled" - @resumable = null - else - @resumable = r diff --git a/src/resumable_server.coffee b/src/resumable_server.coffee index 36fe656..211f63f 100644 --- a/src/resumable_server.coffee +++ b/src/resumable_server.coffee @@ -129,7 +129,7 @@ if Meteor.isServer # Handle HTTP POST requests from Resumable.js or Flow.js resumable_post_lookup = (params, query, multipart) -> - return { _id: share.safeObjectID(multipart?.params?.resumableIdentifier || req.multipart?.params?.flowIdentifier) } + return { _id: share.safeObjectID(multipart?.params?.resumableIdentifier || multipart?.params?.flowIdentifier) } resumable_post_handler = (req, res, next) -> @@ -141,6 +141,7 @@ if Meteor.isServer return resumable = req.multipart.params + resumable.resumableIdentifier = resumable.resumableIdentifier || resumable.flowIdentifier resumable.resumableTotalSize = parseInt resumable.resumableTotalSize || resumable.flowTotalSize resumable.resumableTotalChunks = parseInt resumable.resumableTotalChunks || resumable.flowTotalChunks resumable.resumableChunkNumber = parseInt resumable.resumableChunkNumber || resumable.flowChunkNumber @@ -161,6 +162,7 @@ if Meteor.isServer ((resumable.resumableChunkNumber is resumable.resumableTotalChunks) and (resumable.resumableCurrentChunkSize < 2*resumable.resumableChunkSize))) + console.error("Error in POST params (%d)", req.gridFS.chunkSize, resumable) res.writeHead(501, share.defaultResponseHeaders) res.end() return From 31d7e2e363a1b96e2363d290286f90f2fcdc1273 Mon Sep 17 00:00:00 2001 From: Yoann Ciabaud Date: Fri, 6 May 2016 16:52:08 +0200 Subject: [PATCH 3/3] Remove git modules --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 0c50b06..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "flow.js"] - path = flow.js - url = https://github.com/flowjs/flow.js