Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 39538
1
##############################################################################
2
#
3
# CoCalc: Collaborative Calculation in the Cloud
4
#
5
# Copyright (C) 2016, Sagemath Inc.
6
#
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#
20
###############################################################################
21
22
###
23
Blobs
24
###
25
26
winston = require('winston')
27
28
misc_node = require('smc-util-node/misc_node')
29
misc = require('smc-util/misc')
30
{defaults, required} = misc
31
32
MAX_BLOB_SIZE = 15000000
33
MAX_BLOB_SIZE_HUMAN = "15MB"
34
35
# save a blob in the blobstore database with given misc_node.uuidsha1 hash.
36
exports.save_blob = (opts) ->
37
opts = defaults opts,
38
uuid : undefined # uuid=sha1-based from blob; actually *required*, but instead of a traceback, get opts.cb(err)
39
blob : undefined # actually *required*, but instead of a traceback, get opts.cb(err)
40
ttl : undefined # object in blobstore will have *at least* this ttl in seconds;
41
# if there is already something, in blobstore with longer ttl, we leave it; undefined = infinite ttl
42
check : true # if true, return an error (via cb) if misc_node.uuidsha1(opts.blob) != opts.uuid.
43
# This is a check against bad user-supplied data.
44
project_id : undefined # also required
45
database : required
46
cb : required # cb(err, ttl actually used in seconds); ttl=0 for infinite ttl
47
48
dbg = (m) -> winston.debug("save_blob(uuid=#{opts.uuid}): #{m}")
49
dbg()
50
51
err = undefined
52
53
if not opts.blob?
54
err = "save_blob: UG -- error in call to save_blob (uuid=#{opts.uuid}); received a save_blob request with undefined blob"
55
56
else if not opts.uuid?
57
err = "save_blob: BUG -- error in call to save_blob; received a save_blob request without corresponding uuid"
58
59
else if not opts.project_id?
60
err = "save_blob: BUG -- error in call to save_blob; received a save_blob request without corresponding project_id"
61
62
else if opts.blob.length > MAX_BLOB_SIZE
63
err = "save_blob: blobs are limited to #{MAX_BLOB_SIZE_HUMAN} and you just tried to save one of size #{opts.blob.length/1000000}MB"
64
65
else if opts.check and opts.uuid != misc_node.uuidsha1(opts.blob)
66
err = "save_blob: uuid=#{opts.uuid} must be derived from the Sha1 hash of blob, but it is not (possible malicious attack)"
67
68
if err
69
dbg(err)
70
opts.cb(err)
71
return
72
73
# Store the blob in the database, if it isn't there already.
74
opts.database.save_blob
75
uuid : opts.uuid
76
blob : opts.blob
77
ttl : opts.ttl
78
project_id : opts.project_id
79
cb : (err, ttl) =>
80
if err
81
dbg("failed to store blob -- #{err}")
82
else
83
dbg("successfully stored blob")
84
opts.cb(err, ttl)
85
86
87